Reduxへのより単純な代わりは、ここにあります


Brought to you by engine.so - a tool to instantly create a public self-service knowledge base for your customers with Notion.


導入


“Container”パターンは無名の次のライブラリに導入された概念です.パターンはグローバルなアプリケーション状態のモジュラースライスを保持する様々な「コンテナ」として状態を考えます.この状態を提供するには、アプリケーション間でコンテキストを作成し、フックを介してアクセスできます.
Reduxのような何かと比較して、この容器パターンは、州を管理するフック中心の方法を提供します.それは簡単に学ぶために、あなたのアプリケーションとスケール、およびグローバルな状態について考える直感的な方法を提供します.ここでどのように動作します.

容器のパターンは何ですか。


コンテナーパターンは、1つの外部ライブラリまたはreduxのような“グローバルストア”内のすべてのグローバル状態を持つ代わりに、その状態を“コンテナ”と呼ばれる複数の塊に分割する方法論です.これらのチャンクは、独自の状態を管理する責任があり、次の構文に似たものを使用してアプリケーション内の任意の機能コンポーネントにプルできます.const {user} = Auth.useContainer();このパターンは非常によく機能します.なぜなら、すべてが絡んでいるのではなく、自己管理のチャンクに分割されるからです.各コンポーネントは、使用したい状態のチャンクを簡単にプルし、アプリケーションの状態の一部に依存するだけです.
州の各チャンクは本当に理由が簡単です.それは単にカスタムのフックのコンテキストプロバイダに配線です.それです.「コンテナ」という用語は、単に「反応するカスタムフック+文脈プロバイダー」を意味するラッパー用語であるので、誰かがフック+ usecontextで州管理を推薦するとき、彼らは技術的にこのコンテナパターンを推薦しています.
コンテナーを使用するには、コンテキストをインポートし、フックを使用するだけです.あなたは技術的にどんな外部ライブラリも必要としません、しかし、私はそれがこのパターンをより簡単にする若干の利益を私に与えるので、私は次のように言われていない図書館を使用します.

次は何を言おうか


次の次の小さなライブラリは、これらのグローバルコンテナの理由は少し簡単に役立ちます.このライブラリは小さな(200バイトの小さなような)です、そして、それは基本的に反応の文脈APIがすでにするものの上で何もしないので、それは正当な理由のためです.
このライブラリは、このデザインパターンの100 %オプションです.それだけでコンテキストを簡単に動作するように小さなAPIの改善を提供します.主な利点のいくつかは次のとおりです.
  • タイプチェック:それはあなたのボックスから入力スクリプトをサポートします.これは、反応文脈APIを使用して私のグリッピングの1つだったので、次の未発表のその問題を解決するのを見るのはいいです.
  • エラー処理:あなたがそれを上にコンテクストプロバイダーを持っていないコンテナーにアクセスしようとすると、反応DOMツリーにエラーが発生します.これはデバッグ用のライフセーバーです.
  • について考えるのは簡単です:文脈について考えることは時々抽象的に見えることができます、しかし、「コンテナ」の精神的な概念でこのライブラリを使用することは理由をより簡単になります.
  • このパターンはどのように見えますか?


    ファイル構造


    このパターンを使用すると、すべてのコンテナを「コンテナ」フォルダにsrcディレクトリのルートに置きます.

    私は各コンテナに「コンテナ」という言葉を添えて、コンテナのすべての関連するコードを1つのファイルにすべて配置します.
    これは既にreduxのような利点を持っています.そこでは、1つの責任は3つまたは4つのファイルに分けられます.

    コンテナファイル


    容器は、あなたのスライス状態が生きるところです.このファイルは、状態のこの部分を読み書きするのに必要なすべてを含んでいます.ここにコンテナコンテナファイルがどのように見えるでしょう.
    // The reducer. This would be very similar to your reducer in Redux.
    // This is optional, you can just use useState instead, but this is
    // here to show that if you want to use a reducer and do more
    // complicated state transitions you can.
    function authReducer(state: AuthState, action: Action) {
       ...
    }
    // Custom Hook
    function useAuth(initialState: AuthState) {
       const [state, dispatch] = useReducer(authReducer, initialState);
    const loginWithGoogle = () => {
          dispatch(loggingIn());
          doGoogleLogin()
             .then(user => dispatch(success(user)))
             .catch(err => dispatch(error(err.message)));
       }
    const loginWithEmailPassword = (email, password) => {
          dispatch(loggingIn());
          doEmailPasswordLogin(email, password)
             .then(user => dispatch(success(user)))
             .catch(err => dispatch(error(err.message)));
       }
    const logout = () => dispatch(logout());
    return { 
          user: state.data,
          isAuthenticating: state.loading,
          error: state.error,
          loginWithGoogle,
          loginWithEmailPassword,
          logout
       };
    }
    // Create the Container (this can be a Context too)
    // You just pass in the custom hook that you want to build the
    // container for.
    export const Auth = createContainer(useAuth);
    
    それは基本的にちょうどカスタムフックで、それを容器にするために下のその小さい線であるので、これは本当にきれいです.そのコンテナーコードを下部に追加すると、複数の異なるコンポーネントで使用しても、このカスタムフックは同じ状態になります.これは、未指定の次のコンテナが単にフードの下にコンテキストAPIを使用するためです.
    その作業を行うには、まずすべてのコンテナを格納するアプリケーションにストアを追加する必要があります.これは次のようになります.

    Side-Note: I think there could be a better way to manage a Store like this. If there were a way to dynamically create this structure based on an array of containers or something like that, I think that would be a lot cleaner.
    Also if there was a way to make all these load at the same level of the DOM so any container can access any other container that would be amazing too, but sadly I think that's a limitation with React.


    ルートコンポーネントでこれをスロットにしたいので、rootコンポーネントは次のようになります.
    const App: React.FC = () => {
       return (
          <Store>
             <ReactRouter>
                <AppRoutes>
             </ReactRouter>
          </Store>
       );
    }
    
    とVoila!あなたが正しくこれをしたならば、あなたは現在あなたの反応している構成要素のどれにでも入ることができて、以下のようにこのフックを使うことができなければなりません:
    const LoginPage: React.FC = () => {
       ...
       const {
          formLogin, 
          googleLogin, 
          isAuthenticating,
          user
       } = Auth.useContainer();
       useEffect(() => {
          if (user) {
             history.push('/home');
          }
       }, [user]);
       ...
       return (
          <div>
             <button onClick={() => googleLogin()}>
                Login with Google
             </button>
             ...
          </div>
       );
    }
    
    あなたがすべてを正しくしたならば、このパターンに続いてあなたのために働くべきです!もし何か間違ったことがあったならば、コンテナのプロバイダが作成されていないというエラーが発生します.しかし、基本的な反応コンテキストを使っているなら、本当に追跡するのが難しいバグのための明示的なエラーメッセージだからです.

    なぜRhy Reduxを使用しない?


    Reduxは大規模に国家管理に最適です.それは大きなアプリケーションのための状態を管理する試みとテスト方法です.しかし、そこのアプリケーションの大部分のために、Reduxは始まる間違った場所です.それは非常にboilerplate重いです、そして、あなたの使用ケースがそれを要求するということをすでに知らない限り、あなたに多くの利点を与えそうでありません.
    したがって、私は代替としてこのパターンを提供しています.
    あなたがこのパターンから得る主な利点は、それが開発者の視点からより多くの意味を作るということです.Reduxはすべての状態を取り、ビュー層から離れてプルします.私は、状態を管理するより良い方法がそれを使用するビュー層でそれを割り当てることになると主張するでしょう.
    これは、反応フックが存在する理由です.
    あなたは既にReduxやHooksのようなものから他の状態の動きを使って、この方法論に向かって動いているものを見ることができます.

  • ローカル州=> USENT/Usereducer

  • API状態=>問い合わせ問い合わせ/USEWR/アポロ

  • フォーム状態=>フックフックフォーム/formik
  • したがって、グローバルな状態もフック生態系によく適合するように構築されていることを意味します.

    Since a majority of my state management is done by various hook libraries, it makes sense that my global state management also be hook-centric.


    コンテナパターンはこのアイデアを実装します.それは時間のコストの一部でreduxとしての機能の大部分を提供し、最前線でフック中心の開発と設計されています.
    どんな小さな中小規模のプロジェクトのためにでも、このパターンは、私のためのどんな勇気でもありません.大きなプロジェクトではユースケースに依存します.
    コンテナパターンとreduxの比較を以下に示します:
    コンテナパターンには次の利点があります.
  • Reduxのような何かより少ないボイラープレート.
  • はフードの下でネイティブの文脈APIを使用します.
  • あなたがUSENT、USECONTextとカスタムフックを知っているならば、あなたは10分でAPIを学ぶことができます.
  • は1つの小さなライブラリだけを使用します.
  • また、次のような短所があります.
  • ミドルウェアのサポート.
  • は、Duduxクロムデバッガに類似したツールでありません☹️.
  • 相互に依存関係があるならば、
  • コンテナはある順序で提供されなければなりません.
  • これを念頭に置いて、うまくいけば、あなたのユースケースがRedUxとしてかけがえのないものを要求しないならば、あなたには、どんな種類の選択肢があるかについてより良い考えがあります.
    このパターンを採用したいのですが、Reduxのままにすることはできません.別の選択肢として、Reduxツールキット+ Redux - Ducksパターンを使用します.それがこのコンテナに焦点を当てた方法論を使用するので、あなたが大きなアプリケーションを構築しているならば、Reduxアヒルアプローチはよく働きます、しかし、まだReduxの生態系であなたを保ちます.

    結論


    これがコンテナパターンです.あなたがアプリケーションでReduxを使用して見ているなら、私はあなたのアプリケーションが実際にそれを必要とするかどうかを判断するためのコストを真剣に見てみましょう.私はこのパターンは、関係なく起動するには良い場所だと思うし、それは非常に小さく、モジュール化されているので、将来的には本当に簡単にreduxに移行することができます.
    全体的に、このパターンは、私が私のcodebaseをたくさんきれいにして、アプリケーションを開発するとき、痛み点の私のリストから州管理を削除するのを助けました.
    いずれにせよ、私はあなたが何を考えて、うまくいけばそれはあなたのプロジェクトでうまく動作することをお知らせください.楽しむ!

    このようなより多くのものを見るために、私をチェックしてください:https://spencerpauly.com