この記事はもともとに掲載されました中くらい.
記事上で:
- 大規模なアプリでの支柱掘削に状態管理が優れたソリューションである理由
- 状態管理を使用すると、更新せずにページを更新できます。
- ReduxとMobXは優れたライブラリですが、すべての人に適しているわけではありません。
- さまざまな種類の状態とそれらを保存する場所は何ですか。
- Reactアプリには2つのレイヤーがあります。
- 共有コンポーネントと非共有コンポーネントを理解することの重要性。
OpsRampで働くことで私が気に入っていることの1つは、複雑さを管理したり、困難な開発目標を達成したりするための新しい方法を常に一緒に考え出す方法です。たとえば、アプリケーションの状態の管理。これは歴史的に、フロントエンド開発における最大の課題の1つです。私たちは無駄のないチームなので、より良い方法を見つける必要がありました。この記事では、これをどのように達成するかについて説明します。反応するOpsRampで、そしてあなたがあなた自身の就業日にこれらの慣行のいくつかをどのように適用することができるか。
これまでに使用した中で最も複雑なフロントエンド、「どのようにしてこれを作成したのか」と思わせたサイトについて考えてみてください。これが私のいくつかです:これらのフロントエンドが複雑になる理由は何ですか?
状態管理。フロントエンドは多くのことを「知って」おり、これらのことは重要な方法で相互作用します。したがって、私の見解では、UIを開発する際の中心的な問題は状態管理です。状態管理について以前に知っておいてほしいことがいくつかあります。
#1-状態管理はあなたが軽減する方法です小道具掘削.
重要なReactアプリケーションを構築するには、状態管理を検討する必要があります。サードパーティのライブラリを使用する必要はありません。使用できます。環境。ただし、アプリケーションのどこからでもアクセスできるグローバル状態を保存する方法を理解する必要があります。
例:ダークモードのサポート
アプリにダークモードがあるとします。レンダリングされたすべてのコンポーネントは、UIを適切な色でレンダリングできるように、どのテーマがオンになっているかを認識している必要があります。グローバルUI状態の他の例には、ユーザーがログインしているかどうか、ログインしている個人のユーザー名、グローバル検索ボックスの値などがあります。
小道具の掘削は答えではありません
Reactを学び始めたときはコンテキストが存在しなかったので、この問題を解決するために、 掘削された支柱。アプリが大きくなると、小道具の穴あけは実用的ではなくなります。
状態管理がその答えです
あなたがする必要があるのはあなたのテーマ設定をに保存することです 戻ってきたまた MobX またはプレーンJavaScriptオブジェクトに保存し、Contextを使用してすべてのコンポーネントに渡します。好奇心からReduxについて学ぶまで、状態管理が小道具の掘削問題の解決策であるとは思いもしませんでした。さらに悪いことに、多くの記事では、状態管理なしで重要なWebアプリを構築できると述べています。これにより、最初はそれについて学ぶことすらできなくなりました。
#2-状態管理とは、データを作成/更新した後、更新せずにページを更新する方法です。
問題
ToDoアプリを作成しているとします。ユーザーがToDoアイテムを作成または名前変更した後、To Doリストコンポーネントのみを更新し、ページを更新しないようにします。これどうやってやるの?
ソリューション
解決策は、サーバーからTo Doアイテムのリストを再フェッチしてストアを更新する方法とともに、ToDoアイテムのリストをクライアントのグローバルストアに格納することです。次に、To Doリストコンポーネントは、グローバルストアからToDoアイテムのリストを読み取ります。ユーザーがToDoアイテムを作成または更新した後、To Doのリストを再フェッチするメソッドを呼び出します。これにより、グローバルストアが更新され、コンポーネントが更新されます。クライアント上のやることリストは、クライアント側のキャッシュ、つまりサーバー上のデータのサブセットだと思います。
#3-適切な場所に保存して状態を管理する
選択した状態管理ライブラリにすべてのアプリケーション状態を入れるだけではいけません。代わりに、アプリケーションにはいくつかの異なる種類の状態があることを認識してください。私は触発されていますこのトピックに関するJamesNelsonの投稿.
- データ+ロード状態 フロントエンドがレンダリングするToDoアイテムのリストであり、リストが読み込まれているかどうかを示します。これをRedux / MobX / etcに入れます。
- グローバルUI状態は ユーザーがログインしているかどうか、グローバル検索バーの値。サーバーはこのデータをまったく保存しません。使用する Redux / MobX / etc。
- ローカルUIの状態持っているドロップダウンです たとえば、拡張されました。フロントエンドの残りの部分はこれを気にしません。コンポーネントの状態を使用します。
- フォームの状態 それは フォーム内のフィールドの値であり、ローカルUI状態のサブセットです。次のようなライブラリを使用するFormik フォームを制御されたコンポーネントとして扱います。
- URLの状態ユーザーが現在行っているルートです。window.locationを読み取って更新します。信頼できる唯一の情報源を作成しないでください。
- ページの状態 どこですか コンポーネントが複雑な方法で相互作用するページがありますが、他のページのコンポーネントとは相互作用しません。ページ専用のRedux / MobXストアを作成します(またはコンテキスト付きのプレーンJSオブジェクトを渡します)
#4-Reduxだけでなく他の状態管理ライブラリを学ぶ
Reduxはおそらくアプリケーションには十分ですが、私はそれを使用するのが好きではありませんでした。クライアント上のサーバーからのデータの正規化について心配する必要があるのはなぜですか?なぜ図書館は好きなのですか Redux ORM 存在する必要がありますか?大量のサーバー側コードをクライアントに再実装したくありません。単純な機能を追加するために、複数のファイルに触れて多くの定型コードを記述する必要があるのはなぜですか?アクション/アクションタイプ/アクションクリエーター/リデューサー/ストアとは何ですか?
不変で機能的なコードを書くことの利点は理解していますが、Reduxレデューサーを書くことは不必要に直感的ではないと感じています。アクションでAPI呼び出しを行い、学習や使用をせずにReduxストアを更新したいだけです。 サンク また佐賀.
MobXへの切り替え
それから私はMobXを学びました。各ストアは単なるJavaScriptクラスです。定型文はありません。ストア内の各状態は、単なるクラス変数です。アクションは、@ actionデコレータを持つクラス内の単なるメソッドです。通常と同じように、アクションでAPI呼び出しを行うことができます。呼び出し後に状態を更新するコードをrunInAction。それはサポートします可観測性、私はあまり使用しませんが、便利なツールです。
あなたにぴったりのライブラリを見つけましょう
MobXはあなたのための解決策ではないかもしれません。そうかも知れない apollo-link-state、 記載なし、 xstate、またはを使用した自家製のソリューション環境。要件に合うライブラリが見つかるまで、さまざまなライブラリを学習し続けます。
#5-Reactアプリには2つのレイヤーがあります
状態とビューのレイヤー。 Reactアプリは2つのレイヤーがあると思います。
-
状態とも呼ばれるJavaScriptオブジェクト、およびそれを更新するメソッド。
-
そのJavaScriptオブジェクトをドキュメントオブジェクトモデル(DOM)要素に変換するビューレイヤーであるReactコード。
これは、「UIは状態の関数である」、「Reactは単なるビューレイヤーである」と人々が言うときの意味です。このパラダイムを採用することで、状態を管理するために、UIから切り離されたテスト可能な機能コードを記述できます。そして、あなたのUIは書きやすくなります。 UIに必要なすべてのデータを含むJavaScriptオブジェクトがあり、UIが必要とする方法で構造化されており、このJSONオブジェクトを更新するためのメソッドがあります。この「API」を使用してコンポーネントを簡単に作成できます。
すべての状態管理ライブラリが状態をJavaScriptオブジェクトとして内部に格納するわけではないことを覚えておいてください。しかし、これは私がそれについて考える方法です。もちろん、実際には、上記で書いたように、すべての状態がグローバル状態である必要はありません。
#6-共有コンポーネントと非共有コンポーネント
Reactで最初に書き始めたとき、データフェッチコードをコンポーネントに配置しました。しかし、これは、UIのためだけに別の場所でコンポーネントを使用できないことを意味しました。
-
コンテナコンポーネントのデータを取得しています。 次に、私は読んだ ダンアブラモフの記事 プレゼンテーションコンポーネントとコンテナコンポーネントについて。最初に、データフェッチコードをコンテナコンポーネントに配置しました。各コンポーネントは、プレゼンテーションコンポーネントをレンダリングしました。しかし、作成および更新後にUIを更新するには、データフェッチコードをMobXに配置する必要があることに気付きました(#2を参照)。
-
MobXアクションでデータをフェッチします。 次に、データフェッチコードをMobXアクションに配置します。各コンテナコンポーネントはMobXストアに接続され、プレゼンテーションコンポーネントをレンダリングし、必要に応じてMobXストアからデータとメソッドを小道具として渡しました。残念ながら、これにより、効果的に何もしなかったボイラープレートコンテナコンポーネントをたくさん書く必要がありました。
私は、正しい区別は共有コンポーネントと非共有コンポーネントであると結論付けました。
- 共有: アプリ内の複数の場所にレンダリングする必要があり、プレゼンテーションまたはコンテナのいずれかであるコンポーネント。例:UserSelect、Button
- 非共有: 1か所でのみレンダリングするコンポーネント。例:UserTable、GlobalSearchInput
プレゼンテーションコンポーネントとコンテナコンポーネントの区別は、コンテナコンポーネントではなく、プレゼンテーションコンポーネントを再利用することを前提としています。同意しません。通常、一部のプレゼンテーションコンポーネントを再利用し、他のコンポーネントは再利用せず、一部のコンテナコンポーネントを再利用し、他のコンポーネントは再利用しません。
これは、Reactで可能なことのほんの一部にすぎません。これらのアプローチのいくつかを使用すると、世界で最も複雑なユーザーインターフェースの状態を管理するのに役立ちます。これは、OpsRampでの方法です。なぜなら、結局のところ、FacebookやPalantirほど複雑ではない場合でも、エンドユーザーエクスペリエンスをシームレスでスムーズで満足のいくものにしたいと考えているからです。
次のステップ:
- フォーブス:OpsRampは、2020年に最も働きがいのあるクラウド企業の1つです。
- 私たちについて読む 2020年冬のリリース ブログで。
- 申し込む OpsRampブログへ!