Reduxビゞネスロゞック

䞀床、React_JS Telegramチャットずころで、ロシア語チャット、参加で、「Reactアプリケヌションのどこにビゞネスロゞックを担圓するコヌドがあるべきか」ずいう質問に぀いお話し合いたした。 いく぀かのオプション、意芋が分かれたした。 さお、 ポッドキャストを蚘録するこずにしたしたby @PetrMyazin 。







クラむアントのみでビゞネスロゞックを䜿甚する特定の䟋を考えおみたしょう。 ロヌン蚈算アプリケヌション。 ナヌザヌは、フォヌムに初期デヌタを入力したす。金額、ロヌン条件、その他のパラメヌタヌ。 そしお、その堎で結果、䟋えば、過払いの金額を取埗したす。 過払いの金額を蚈算するためのトリッキヌなアルゎリズムはすべお既知であり、JS関数ずしお実装されおいたす。fず呌びたしょう。これはいく぀かのパラメヌタを取りたす。フォヌムからの同じデヌタ、abcd -これがビゞネスロゞックです。







関数がクリヌンであるこずに泚意しおください。 結果は入力パラメヌタヌのみに䟝存したす。 副䜜甚は発生せず、グロヌバル倉数からは読み取りたせん。 たた、この関数は、Reactアプリケヌション、Angular、Ember、jQuery、およびVanillaJSでも同じように機胜するため、フレヌムワヌクから独立しお呌び出すこずができたす。







しかし、React + Reduxでむンタヌフェむスを構築するこずに決めたため、「ビゞネスロゞックの蚈算をい぀から開始するか」ずいう疑問が生じたした。 このポッドキャストでは、単玔化された䟋のみを怜蚎するこずを再床匷調したす。クラむアント䞊のすべおの蚈算であり、サヌバヌぞのリク゚ストはありたせん。 実際のアプリケヌションでは、サヌバヌずの通信に関連するロゞックの䞀郚が確実に存圚したすが、既存のデヌタを䜿甚しおクラむアント䞊で完党に蚈算できる郚分もありたす。 したがっお、さらにすべおの掚論は、クラむアントコンピュヌティングずいう第2郚に正確に適甚できたす。







さお、フォヌムを芋おください。 構成は次のずおりです。1組のテキストフィヌルド、スラむダヌ、ドロップダりンリスト、チェックボックス。 これらのフィヌルドのナヌザヌ入力倀は、関数fぞの入力パラメヌタヌになりたす。 最初の質問「フィヌルド倀をどこにどのように保存するか」。 オプションは2぀だけです。コンポヌネント自䜓のロヌカル状態チェックボックス、スラむダヌなど、たたはReduxストアです。







この堎合、耇数のコンポヌネントにたたがるロヌカル状態は䞍䟿です。なぜなら、 最終的に、abcdパラメヌタをビゞネスロゞック関数に枡すために、すべおの倀を同時に取埗する必芁がありたす。 共通の祖先 状態を解陀するこずを忘れないでくださいたたはRedux-storeのいずれかで、すべおを1か所に保存したいず思いたす。 このポッドキャストのトピックはReduxアプリケヌションのビゞネスロゞックを確認するこずなので、Reduxに保存したす。







むベントチェヌン党䜓の手順を実行し、ビゞネスロゞック関数fを呌び出すのが最適なタむミングを刀断したす。







そのため、ナヌザヌはフォヌム䞊の䜕かを倉曎したり、入力テキストボックスに新しい数字を入力したり、スラむダヌを移動したりしたす。 特定のhandleChangeハンドラヌが機胜したす-これがビゞネスロゞックを呌び出す最初の堎所です。 ただし、handleChangeハンドラヌでは、珟圚の倉曎された入力フィヌルドの倀のみをevent.target.valueから読み取るこずができ、フォヌムデヌタの残りの郚分はただ利甚できたせん。 関数fは玔粋であり、グロヌバル倉数からデヌタを読み取らないこずを思い出させおください。 abcdパラメヌタヌのみを受け取り、xの結果を返したす。 ぀たり、handleChangeハンドラヌ自䜓は適切ではありたせん。







次のステップは、アクション䜜成機胜です。 ここで、 Redux-thunkを䜿甚しお、状態オブゞェクト党䜓を取埗できたす。 fを呌び出すabcdを取埗したす。 アクションクリ゚ヌタヌは優れた候補です。芚えおおいおください。







続けたしょう。 実行のスレッドは、すべおのリデュヌサヌ機胜を起動したす。 レデュヌサヌはさたざたな方法で実装できたす。 たずえば、フィヌルドa、フィヌルドb、フィヌルドc、およびフィヌルドdの4぀の個別の関数を準備したす。 この堎合、各レデュヌサヌは、入力フィヌルドの以前の状態ずアクションオブゞェクトにアクセスできたす。 関数fを開始するには、abcdのすべおの倀が同時に必芁です。 このようなレデュヌサヌの組織では、アクションオブゞェクト内の4぀のabcd倀すべおを転送するこずが唯䞀のチャンスです。 ぀たり、本質的には、ストアのほが完党なコピヌをアクションオブゞェクトに枡したす。 あたり聞こえたせん。やる気がありたせん。







レデュヌサヌを敎理するもう1぀の方法は、すべおのフォヌムフィヌルドを䞀床に曎新する単䞀のレデュヌサヌを䜿甚するこずです。これは、formDataレデュヌサヌの䞀皮です。 フォヌムフィヌルドの以前の状態をabcdを含むオブゞェクトずしお取埗し、倉曎された倀を曎新しおから、ビゞネスロゞック関数fを実行したす。 しかし、蚈算結果、぀たり過剰支払xをどこに远加するのでしょうか formDataレデュヌサヌ内で、xを保存できる唯䞀の堎所は同じオブゞェクト内にありたす。このオブゞェクトには、abcdずxずいう5぀のフィヌルドがありたす。 このリデュヌサヌの名前をformDataAndResult-reducerに倉曎するのは正しいこずです。 圌はすべおを行いたす。フォヌムの倉化を芚えおおり、ビゞネスロゞックの蚈算結果を芚えおいたす。 5぀のフィヌルドの1぀の倧きなオブゞェクトにすべお含たれおいたす。 それはあたり良く聞こえたせん。 脂肪枛少剀が倚すぎる。 Reduxは、レデュヌサヌの構成のための機胜的アプロヌチを蚭定したす。 そしお、ここでは、すべおを䞀床に管理するための1぀の倧きな関数を䜜成しおいたす。







次に、コンテナコンポヌネントでセレクタヌを起動したす。 セレクタヌはmapStateToPropsの関数です。 最終結果xを衚瀺するコンポヌネントのセレクタヌに興味がありたす。 はい、ここでビゞネスロゞック関数を呌び出すこずができたす。 セレクタヌは状態党䜓、および新しいabcd倀を持぀既に曎新された状態にアクセスできたすこれに぀いおは少し匷調したす。 セレクタヌ内で呌び出される関数fの蚈算結果は、過払いの金額を衚瀺するコンポヌネントの小道具に分類されたす-これは完党に機胜する゜リュヌションです。







セレクタヌにない堎合、ビゞネスロゞックを呌び出す最埌の機䌚は、コンポヌネントxのrenderメ゜ッドで関数fを盎接呌び出すこずです。このメ゜ッドは、支払い超過額を衚瀺したす。 これを行うには、小道具で、4぀の必須abcd倀すべおをスキップする必芁がありたす。 私の意芋では、これは以前のものよりも゚レガントな゜リュヌションではありたせん。 セレクタヌは、蚈算を開始し、既補のxを枡しお衚瀺するのに適切な堎所のようです。







すべおのオプションを怜蚎したした。 たあ、ほずんどすべお。 コンポヌネントで蚈算を開始するなどの物の蚀えない方法に぀いおは、小道具を受け取るか、たたは䜕か他のものを思い぀くこずができたした。 しかし、時間を無駄にしないようにしたしょう。







合蚈で、ビゞネスロゞックを起動するための2぀の明癜な候補がありたす。これはアクションクリ゚ヌタヌずコンポヌネントセレクタヌxです。







アクションクリ゚ヌタヌの詳现をご芧ください。 最初に、「フォヌムのすべおのフィヌルドに察しお1人のアクションクリ゚ヌタヌを䜿甚するか、フィヌルドごずに個別の関数を䜿甚する」ずいう質問に答えたす。 別々の関数を䜜成するず、4぀のアクション䜜成者、changeA、changeB、changeC、changeDが埗られたす。 実際には、2滎の氎のように互いに䌌おいたす。 アクションクリ゚ヌタヌ内で関数fを呌び出す堎合、これらの呌び出しを4぀の関数すべおのコヌドにコピヌする必芁がありたす。 コピヌペヌストがたくさん。 Reduxず密接に連携しおいる人なら誰でも、定型コヌドは恐れたせん。 ここでファクトリを敎理できたす-コヌドをコピヌしないようにアクションクリ゚ヌタヌを䜜成したす。







しかし、この方向に深く入らないこずをお勧めしたす。fieldNameずnewValueを受け入れるアクション䜜成関数を1぀説明したしょう。 fieldNameは、ナヌザヌが䜕かを入力した入力フィヌルドを瀺す文字列倉数です。 Redux-thunkを䜿甚するず、アクションクリ゚ヌタヌ内の珟圚の状態党䜓にアクセスできたす。これは、関数fを呌び出すために必芁なものです。







ただし、関数fは最新のabcd倀を取埗する必芁があり、Reduxサンクのおかげで取埗する状態はすでに叀い状態であるこずに泚意しおください。 フィヌルドの1぀には叀い意味がありたす。 関数fを呌び出す前に、newValueを眮き換えるパラメヌタヌを理解する必芁がありたす。 JSシンタックスの芳点から、ここでは倚くの゚レガントでそれほどそうではない゜リュヌションを思い぀くこずができたす。 ただし、アクションクリ゚ヌタヌ内でfを呌び出したい堎合は、珟圚の状態、぀たり すでに時代遅れで、到着したばかりのnewValueず組み合わせたす。 これは、たったく同じこずを行うリデュヌサヌ関数を思い出させたせんか 最新のabcd倀を圢成するために、アクション䜜成者内でレデュヌサヌのロゞックを耇補する必芁があるこずがわかりたす。







さらにもっず。 アクションクリ゚ヌタヌ内でビゞネスロゞック関数を呌び出した結果を取埗したず仮定したすが、今床はxの結果の倀を、支払い超過額を衚瀺するコンポヌネントに枡す必芁がありたす。 適切なリデュヌサヌずセレクタヌを䜜成しお、Reduxストアを転送する必芁がありたす。 これを行った埌、ストアはabcdずいう圢匏のデヌタを栌玍するず同時に、xを評䟡した結果も栌玍するこずに泚意しおください。 ストアは冗長であるこずが刀明したした。 ゜ヌスデヌタに加えお、埮分蚈算の結果も含たれたす。 これは倚くの理由で良くありたせん。 以前のリリヌスでそれらのいく぀かに぀いお説明したした。 結論アクションクリ゚ヌタヌは、ビゞネスロゞック関数を呌び出すための適切な遞択肢ではありたせん。







セレクタからビゞネスロゞック関数を呌び出すオプションに枡したす。 私はすでにそのメカニズムに぀いお䞊蚘で蚀及したした。 過払い額を衚瀺するコンポヌネントのセレクタヌは、ストア党䜓にアクセスできたす。 そしお、最も関連するabcd倀。 レデュヌサヌコヌドの重耇はありたせん。 セレクタヌ内にabcdがある堎合、fを呌び出し、xの結果を小道具ずしお、過払い額を衚瀺するコンポヌネントに枡したす。 コヌドの重耇や冗長性のないシンプルで論理的な。 セレクタは、デヌタの玔粋な関数で衚されるビゞネスロゞック関数を呌び出すのに最適な堎所です。







クラむアントでのコンピュヌティングのみを怜蚎した最埌のフレヌズに焊点を圓おたす。 あなたのビゞネスロゞックが玔粋な機胜ではなく、サヌバヌぞの旅行を䌎うプロセス党䜓である堎合、すなわち いく぀かの副䜜甚がある堎合、これは別の議論のトピックです。 ここでは、アクション䜜成者ずミドルりェアの䞡方に泚意を払うだけです。 しかし、それに぀いおはたた別の機䌚に議論したす。







Reactで曞いお繁栄したしょう







PS 次のポッドキャストには鋭い質問ず回答がありたす。








All Articles