ReactReduxアプリケーションアーキテクチャ

序文



これはHabréに関する私の最初の投稿なので、あまり厳しく判断しないでください(まあ、または判断しますが、建設的に)。



このアプローチでの私にとっての主な利点は、モジュールごとにビジネスロジックを明確に描写して委任できることです。1つのモジュールは、1つのことと非常に具体的なことを担当します。つまり、このアプローチでは、開発プロセス中に、「ここでこれを(より正確に)どこで行うのがよいか」という考えはありません。このアプローチでは、タスク/問題をどこで正確に解決する必要があるかがすぐにわかります。



ファイル構造



プロジェクト構造+が標準です。アセンブリ自体の構成要素から何が使用されているかを簡単に説明します







  • 非同期アクションを準備するために、私はsagaミドルウェアを使用します-サンクミドルウェアに関してはるかに柔軟で強力なものです

  • css-modulesスタイリングコンポーネントがあります。実際、コンセプトはスタイル付きコンポーネントのコンセプトと同じですが、どういうわけか私にとってはより便利です
  • ストアからコンポーネントにスローされる小道具を制御するコンテナとコンポーネント間の中間層(フィルタリング、メモ化、およびアプリケーション状態の任意の部分のフィールド名を便利に操作する機能)-再選択


Redux sagas



Redux sagasのドキュメントsagas



の主な本質は(だけでなく)、モジュールごとに要求を処理するビジネスロジックを分離することです。各サガは、APIの独自の部分を担当します。ユーザーデータを取得し、受信が成功したときにアクションを呼び出す必要がある場合は、別のモジュールで実行しますusersSagas.js sagasを支持



する主な要因(私にとって)は次のとおりです。UPD

promise-hellに関するポイントを追加)

  • 1)友好的な方法で、アクションはオブジェクトを与える単なる関数でなければならないという事実。いくつかのアクションが異なって見える場合(そしてこれがサンクの使用でどのように起こるか)、どういうわけかこれは単一の概念に適合しないので、私はどういうわけかそれらを1つの形式にしたいと思います。リクエストのロジックを移動し、リクエストのデータを別のモジュールに移動したいと思います-これがsagasの目的です

  • 2)原則として、以前のリクエストへの応答からのデータを使用する複数のリクエストを行う必要がある場合(中間データをストアに保存しますか?)、Redux-thunkは、別のリクエストを呼び出す新しいアクションを作成するように招待しますasync-actionリクエスト。同じ繰り返しがさらに2回(たとえば)行われます。それは約束のようです-地獄で、通常は散らかっていて、原則として、使用するのに不便です(入れ子が多すぎます)私は









css-モジュール/スタイル付きコンポーネント



プロジェクトでは、一般的なcssモジュールでコンポーネントのスタイルを設定するためのルールを作成していることがよくあります。



私は完全に反対です。コンポーネントは分離されたシステムです。可能な限り再利用可能である必要がありますしたがって、個別にスタイルを設定すると便利です。











再選択



セレクターにはいくつかの目標があります。



  • , . , , ( , ). , , . - getFilteredItems,
  • ,
  • . - . - . friends. , . , . , , friends contacts. reselect , , . — .


すべてのくしゃみごとにリセットするという事実に私が溺れているのは最後のポイントのためです。再選択-記憶のためだけでなく、アプリケーション状態ツリーの描画をより便利に行うためにも







コンポーネントとコンテナ



Reactへの従来のアプローチ(ストアを個別のエンティティとして格納するためのライブラリを使用しない)には、2つのタイプのコンポーネント(PresentationalとContainer-Components)があります。通常(私が理解しているように)、これは厳密なフォルダー分割ではなく、概念的な分割です。



プレゼンテーションのコンポーネントは愚かです。実際、それらは小道具としてそれらに投げ込まれたデータのレイアウトと表示だけです。 (このようなコンポーネントの例は、上記のcss-modulesにあります)



Container-Components-たとえば、コンポーネントのライフサイクルを操作するロジックをカプセル化するコンポーネント。たとえば、データの要求を担当するアクションを呼び出す責任があります。レイアウトはPresentational-Componentsで分離されているため、最小限のレイアウトを返します。



例+-Container-Component:







Redux Containersは、実際には、redax側とreactコンポーネントの間のレイヤーです。それらの中で、セレクターを呼び出し、コンポーネントの反応小道具にアクションをスローします。



私はAMのため、すべてのくしゃみのために、独自のコンテナを持ちます。まず、コンポーネントにスローされる小道具をより細かく制御できます。次に、再選択を使用してパフォーマンスを制御できます。



1つのコンポーネントを再利用する必要があるが、ストアのさまざまな部分で再利用する必要がある場合がよくあります。このためには、別のコンテナを作成し、必要に応じて返す必要があることがわかりました。つまり、多対1の関係(多くはコンテナであり、1つはコンポーネントです。私にとっては便利で概念的に)



また、ほとんどのコンポーネントをコンテナ化することを支持する、より頻繁な例を示したいと思います。



いくつかのAPIから受け取るデータの配列(たとえば、ユーザーの配列)があります。また、お客様が拒否することのない無限の巻物もあります。非常に長い間スクロールダウンし、約1万以上のデータをロードしました。そして今、1人のユーザーのいくつかのプロパティを変更しました。私たちのアプリケーションは、次の理由で大幅に遅くなります。



  1. ユーザーのリストを含むページ全体にグローバルコンテナを添付しました
  2. ユーザー配列の1つの要素の1つのフィールドを変更すると、新しい要素とインデックスがユーザーレデューサーに返される新しい配列
  3. UsersPageコンポーネントのツリーに配置されたすべてのコンポーネントが再描画されます。各ユーザーコンポーネント(配列要素)を含む


どうすればこれを回避できますか?



コンテナを作ります



  • ユーザーとの配列
  • 配列要素(1ユーザー)


その後



、「array withusers」コンテナにラップされたコンポーネントで、キー(react required prop)がスローされた「arrayelement(oneuser)」コンテナを返します。indexmapStateToPropsの「arrayelement(oneuser)」コンテナでは、2番目です。引数として、コンテナが返すコンポーネントのownPropsを取得します(インデックスの中で)。インデックスによって、アレイの1つの要素のみをストアから直接引き出します。



さらに、それがためにはるかに容易になるだろうの再描画の最適化だけで変更された要素を(減速中に、我々は返すマップのいくつかの種類作られているため、アレイ全体が、再描画されるNEWの各要素のための新たな指標を持つ配列を) -ここでは、選択し直すに助けされる



コンテナを:







コンテナ要素:







element-selector:







何か追加があれば、コメントで喜んで読みます。



All Articles