この記事は、Vildan Softicによって査読されました。 SetePointのコンテンツを完璧にしてくれたSetePointのすべてのピアレビューアに感謝します!
私は、ゼロから始めて、すべてがどのように機能するかを理解するのが好きな開発者のようなものです。私はこれが自分自身に(不必要な)ワークロードをもたらすことを知っていますが、特定のフレームワーク、ライブラリ、またはモジュールの背後にあるメカニズムを理解し理解するのに役立ちます。
最近、私は再びこの瞬間を経験し、ReduxとPure JavaScriptを使用してWebアプリケーションの開発を開始しました。この記事では、アプリケーション構造の概要を説明し、早期(最終的に失敗した)反復を調べてから、最終的に選択したソリューションと学んだことを見たいと思います。
キーポイント
- Reduxは、純粋なJavaScriptを使用して、Reactに依存せずにアプリケーション状態を管理し、異なるUI層での状態管理における柔軟性を実証できます。
- reduxストレージを適切に初期化および管理することが重要です。
- 必要なデータのみが保存されていることを確認するために、ユースケース駆動型ストレージを実装することをお勧めします。
設定
最新のフロントエンドテクノロジーを使用して高速で強力なWebアプリケーションを構築する人気のあるReact.JSとReduxの組み合わせを聞いたことがあるかもしれません。Reactは、ユーザーインターフェイスを構築するためにFacebookが作成したコンポーネントベースのオープンソースライブラリです。 Reactは単なるビューレイヤーですが(
Reduxの利点は、できるだけ早くアプリケーションの設計を前進させ、理解することを強制することです。実際に保存すべきもの、どのデータを変更できるか、変更する必要があるか、どのコンポーネントがストレージにアクセスできるかを定義し始めます。しかし、Reduxは状態にのみ焦点を合わせているため、アプリケーションの残りの部分を構築および接続する方法について少し混乱しています。 Reactはすべてのステップを導くという素晴らしい仕事をしますが、それがなければ、何が最適かを把握する必要があります。 問題のアプリケーションは、いくつかの異なるビューを持つモバイルファーストテトリスクローンです。実際のゲームロジックはReduxで行われますが、オフライン機能はLocalStorageおよびカスタムビュー処理によって提供されます。リポジトリはGitHubで見つけることができますが、アプリはまだアクティブな開発中に開発されており、開発中にこの記事を書きました。
アプリケーションアーキテクチャを定義します
ReduxおよびReact Projectsで一般的なフォルダー構造を採用することにしました。これは、さまざまな設定で機能する論理構造です。このトピックには多くのバリエーションがあり、ほとんどのプロジェクトはわずかに異なりますが、全体的な構造は同じです。
src/scripts/
<code>actions/
├── game.js
├── score.js
└── ...
components/
├── router.js
├── pageControls.js
├── canvas.js
└── ...
constants/
├── game.js
├── score.js
└── ...
reducers/
├── game.js
├── score.js
└── ...
store/
├── configureStore.js
├── connect.js
└── index.js
utils/
├── serviceWorker.js
├── localStorage.js
├── dom.js
└── ...
index.js
worker.js</code>
私のタグは別のディレクトリに分離され、単一のindex.htmlファイルによってレンダリングされることになります。この構造は、スクリプト/コードベース全体で一貫したアーキテクチャを維持するために類似しています。
src/markup/
<code>layouts/
└── default.html
partials/
├── back-button.html
└── meta.html
pages/
├── about.html
├── settings.html
└── ...
index.html</code>
ストレージの管理とアクセス
ストレージにアクセスするには、アプリケーションのすべてのインスタンスに1回作成して渡す必要があります。ほとんどのフレームワークは、ある種の依存関係噴射コンテナを使用しているため、フレームワークユーザーとして自分でソリューションを作成する必要はありません。しかし、自分のソリューションを使用するとき、どうすればすべてのコンポーネントで利用できるようにすることができますか?
私の最初の反復は失敗しました。なぜこれが良いアイデアだと思うのかわかりませんが、ストレージを独自のモジュール(Scripts/Store/Index.js)に入れて、その後、残りのアプリケーションでインポートできます。私はそれを後悔し、すぐに円形の依存関係を扱いました。問題は、コンポーネントがストレージにアクセスしようとすると、ストレージが正しく初期化されないことです。取り組んでいる依存関係の流れを示すためのチャートを作成しました。
アプリケーションのエントリポイントは、すべてのコンポーネントの初期化され、直接またはヘルパー関数を介して内部的にストレージを使用しています(ここではconnectと呼ばれます)。ただし、ストレージは明示的に作成されるのではなく、独自のモジュールの副作用にすぎないため、コンポーネントは作成される前にストレージを使用します。コンポーネントまたはヘルパー関数が最初に保存される時間を制御することはできません。これは非常に混乱しています。
ストレージモジュールは次のとおりです
scripts/store/index.js
(☓bad)
上記のように、
ストレージは副作用として作成され、エクスポートされます。ヘルパー機能も保存する必要があります。 import { createStore } from 'redux'
import reducers from '../reducers'
const store = createStore(reducers)
export default store
export { getItemList } from './connect'
scripts/store/connect.js
(☓bad)
これはまさに私のコンポーネントが互いに繰り返される瞬間です。ヘルパー関数は、ストレージを実行する必要があり、アプリケーションの他の部分にアクセスできるように、ストレージ初期化ファイルから同時にエクスポートされます。これがどれほど乱雑に聞こえるのかわかりますか? import store from './'
export function getItemList () {
return store.getState().items.all
}
solution
今は明らかなようで、理解するのに時間がかかりました。初期化をアプリケーションエントリポイント(Scripts/index.js)に移動し、必要なすべてのコンポーネントに渡すことでこれを解決しました。
繰り返しますが、これは、Reactが実際にストレージにアクセスできるようになる方法と非常に似ています(ソースコードを参照)。彼らが一緒にうまく機能する理由はありますが、その概念を学んでみませんか?

アプリケーションエントリポイントは、最初にストレージを作成し、次にすべてのコンポーネントに渡します。コンポーネントは、ストレージおよびスケジュール操作に接続したり、変更をサブスクライブしたり、特定のデータを取得したりできます。
変更を見てみましょう:
scripts/store/configureStore.js
(✓Good)
モジュールを保持しましたが、代わりに、コードベースの他の場所にストレージを作成するConfigureStoreという関数をエクスポートしました。 これは単なる基本的な概念であることに注意してください。 <code>actions/
├── game.js
├── score.js
└── ...
components/
├── router.js
├── pageControls.js
├── canvas.js
└── ...
constants/
├── game.js
├── score.js
└── ...
reducers/
├── game.js
├── score.js
└── ...
store/
├── configureStore.js
├── connect.js
└── index.js
utils/
├── serviceWorker.js
├── localStorage.js
├── dom.js
└── ...
index.js
worker.js</code>
scripts/store/connect.js(✓Good)
接続ヘルパー関数は基本的に変更されていませんが、ストレージをパラメーターとして渡す必要があります。最初は、このソリューションを使用することをためらいました。今、私はそれらがすべてを読みやすくするのに十分であり、十分に進んでいると思います。
scripts/index.js
<code>layouts/
└── default.html
partials/
├── back-button.html
└── meta.html
pages/
├── about.html
├── settings.html
└── ...
index.html</code>
これがアプリケーションのエントリポイントです。ストアは作成され、すべてのコンポーネントに渡されます。 PageControlsは、特定のアクションボタンのグローバルイベントリスナーを追加し、TetrisGameは実際のゲームコンポーネントです。ここでストレージを移動する前に基本的に同じように見えますが、ストレージをすべてのモジュールに個別に渡すことはありません。前述のように、コンポーネントは私の失敗した接続法を介してストレージにアクセスできます。
コンポーネント
2つのコンポーネントを使用することにしました:import { createStore } from 'redux'
import reducers from '../reducers'
const store = createStore(reducers)
export default store
export { getItemList } from './connect'
プレゼンテーションレイヤーおよび
コンテナコンポーネント。プレゼンテーションコンポーネントは、純粋なDOM処理以外は何もしません。一方、コンテナコンポーネントはアクションをスケジュールしたり、変更を購読したりできます。
Dan AbramovはReactコンポーネントの素晴らしい記事を書きましたが、この一連のメソッドは他のコンポーネントアーキテクチャにも適用できます。
しかし、私には例外があります。コンポーネントは非常に小さく、1つだけのことを行うことがあります。上記のパターンの1つに分割したくないので、混ぜることにしました。コンポーネントが成長し、より多くのロジックを取得した場合は、分離します。
スクリプト/コンポーネント/pagecontrols.js
上記の例はコンポーネントの1つです。要素のリスト(この場合、データアクション属性を持つすべての要素)があり、属性コンテンツに基づいてクリックするとアクションをスケジュールします。それだけです。その後、他のモジュールはストレージの変更を聞き、それに応じて自分自身を更新する場合があります。前述のように、コンポーネントにもDOMアップデートがある場合は、分離します。
さあ、これら2つのコンポーネントタイプの明確な分離を示しましょう。
更新dom
import store from './'
export function getItemList () {
return store.getState().items.all
}
プロジェクトを始めたときに私が抱えていたより大きな問題は、実際にDOMを更新する方法でした。 Reactは、仮想DOMと呼ばれるDOMの高速インメモリ表現を使用して、DOMの更新を最小限に抑えます。
私は実際に同じことをすることを考えています。私のアプリケーションが大きくなり、domがより退屈である場合、仮想domに切り替えるかもしれませんが、今のところclassicdom操作をしています。 Reduxでうまく機能します。
基本的なプロセスは次のとおりです
コンテナコンポーネントの新しいインスタンスを初期化し、内部使用のためにストレージを渡します-
コンポーネントのサブスクリプションストレージの変更
-
および異なるプレゼンテーションレイヤーコンポーネントを使用してDOMで更新をレンダリング-
注:私はJavaScriptのDOMに関連するものの$シンボルプレフィックスのファンです。ご想像のとおり、jqueryの$から取られています。したがって、純粋なプレゼンテーションコンポーネントファイル名には、ドル記号が付いています。
scripts/index.js
<code>actions/
├── game.js
├── score.js
└── ...
components/
├── router.js
├── pageControls.js
├── canvas.js
└── ...
constants/
├── game.js
├── score.js
└── ...
reducers/
├── game.js
├── score.js
└── ...
store/
├── configureStore.js
├── connect.js
└── index.js
utils/
├── serviceWorker.js
├── localStorage.js
├── dom.js
└── ...
index.js
worker.js</code>
ここでは何も派手なものではありません。コンテナコンポーネントScoreObserverをインポート、作成、および初期化します。それは正確に何をしますか?スコアに関連するすべてのビュー要素を更新します:ゲーム中のハイスコアリストと現在のスコア情報。
スクリプト/コンポーネント/scoreobserver/index.js
<code>layouts/
└── default.html
partials/
├── back-button.html
└── meta.html
pages/
├── about.html
├── settings.html
└── ...
index.html</code>
これは単純なコンポーネントであることを忘れないでください。ここで何が起こっているのですか? ScoreObserverコンポーネントは、ストレージへの内部参照を保存し、後で使用するために新しいインスタンスの2つのプレゼンテーションレベルコンポーネントを作成します。 initメソッドは、ストレージの更新をサブスクライブし、ストレージが変更されるたびに$ラベルコンポーネントを更新しますが、ゲームが実際に実行されている場合のみです。
updatescoreboardメソッドは他の場所で使用されます。とにかくビューが非アクティブであるため、変更が発生するたびにリストを更新することは意味がありません。また、ビューが変更されるたびに異なるコンポーネントを更新または非アクティブ化するルーティングコンポーネントもあります。そのAPIはほぼ次のとおりです
import { createStore } from 'redux'
import reducers from '../reducers'
const store = createStore(reducers)
export default store
export { getItemList } from './connect'
注:$(および$$)はjQueryの参照ではなく、document.queryselectorの便利なユーティリティショートカットです。
スクリプト/コンポーネント/scoreobserver/$ board.js
繰り返しますが、これは基本的な例であり、基本的なコンポーネントです。更新ボード()メソッドは配列を取り、それを反復し、スコアリストにコンテンツを挿入します。 import store from './'
export function getItemList () {
return store.getState().items.all
}
スクリプト/コンポーネント/scoreobserver/$ label.js
このコンポーネントは、上記のスコアボードとほぼ同じですが、単一の要素のみを更新します。 import { createStore } from 'redux'
import reducers from '../reducers'
export default function configureStore () {
return createStore(reducers)
}
その他のエラーと提案
もう1つの重要なポイントは、
ユースケース駆動型ストレージを実装することです。アプリケーションに不可欠なコンテンツを保存することだけが重要だと思います。最初は、現在のアクティブビュー、ゲーム設定、スコア、ホバーエフェクト、ユーザーの呼吸モードなど、すべてを保存しそうになりました。
これは1つのアプリケーションに関連している可能性がありますが、別のアプリケーションとは何の関係もありません。現在のビューを保存し、リロード時にまったく同じ場所で続行するのはいいことかもしれませんが、私の場合、それは有用ではなく、ユーザーエクスペリエンスが悪いと感じていました。メニューやモーダルスイッチを保存したくありませんよね?なぜユーザーはその特定の状態に戻る必要があるのですか?大規模なWebアプリケーションでは、これは理にかなっているかもしれません。しかし、私の小さなモバイルゲームフォーカスゲームでは、そこから離れたからといって設定画面に戻ります。これはかなり迷惑です。
結論
私は反応の有無にかかわらずReduxプロジェクトを行ったことがありますが、私の主なポイントは、アプリケーション設計の大きな違いは必要ないということです。 Reactで使用される方法のほとんどは、実際に他のビュー処理設定に適合できます。これを実現するのにしばらく時間がかかりました。最初は何か違うことをしなければならないと思ったので、それが必要ではないことに気づきました。
しかし、違うのは、モジュールの初期化、それらの保存方法、およびコンポーネントがアプリケーションの全体をよく理解していることです。概念は同じままですが、実装とコードのボリュームはニーズに最適です。
Reduxは、アプリケーションをより思慮深い方法で構築するのに役立つ優れたツールです。ビューギャラリーなしで単独で使用することは、最初は非常に注意が必要ですが、最初の混乱を克服すると、何も止めることはできません。
私の方法についてどう思いますか? reduxとさまざまなビューを使用して、設定だけを処理していますか?私はあなたから聞いて、コメントでそれについて話し合いたいです。
Reduxの詳細については、「Design Issuesを解決するためにReduxの書き換えとテスト」ミニコースをご覧ください。このコースでは、WebSocket接続を通じてトピックごとに整理されたツイートを受信するReduxアプリケーションを構築します。何が起こるかについてのアイデアを提供するには、以下の無料コースをご覧ください。
プレーヤーのロード…FAQは、反応のないredux(FAQ)にあります
Reduxを使用することとReactを使用しないこととReactを使用しないことの主な違いは何ですか?
Reduxは、任意のUIレイヤーで使用できるJavaScriptアプリケーション用の予測可能な状態コンテナです。 ReduxとReactの使用とReactを使用しないことの主な違いは、UI層がReduxストレージとどのように相互作用するかです。 Reactで使用すると、ReduxはReactのコンポーネントベースのアーキテクチャとそのライフサイクルアプローチを活用して、状態の変更が行われたときにコンポーネントの更新を自動的に処理することができます。反応がなければ、ステータスが変更されたときにストレージを手動で購読し、UIの更新を処理する必要があります。
反応せずにreduxで非同期操作を処理する方法は?
Reduxの非同期操作は、通常、Redux ThunkやRedux Sagaなどのミドルウェアを使用して処理されます。これらのミドルウェアを使用すると、通常のオブジェクトではなく、機能(サンク)またはより複雑な非同期操作(SAGAS)をスケジュールできます。反応がなくても、これらのミドルウェアをReduxストレージで使用できます。 ReduxのApplyMiddleware機能を使用してストレージを作成するときは、ミドルウェアを適用するだけです。
反応せずにredux devtoolsを使用できますか?
はい、Redux DevtoolsはReactに依存せず、Reduxを使用する任意のUI層で使用できます。 Redux DevToolsをアプリケーションに統合して、Reduxストレージを作成するときにミドルウェアとして追加できます。これにより、Reactがなくても、アプリケーションのステータスとアクションをリアルタイムで確認できます。
ReactなしでUIコンポーネントのReduxストレージに接続する方法は?
反応とその接続関数なしでは、Reduxストレージを手動でサブスクライブし、状態が変更されたときにUIコンポーネントを更新する必要があります。 store.subscribeメソッドを使用してストアを購読できます。これは、操作がスケジュールされるたびに呼び出されるリスナー関数を取得します。このリスナー関数では、store.getStateを使用してストレージの現在の状態を取得し、それに応じてUIコンポーネントを更新できます。
他のライブラリやVueやAngularなどのフレームワークでReduxを使用できますか?
はい、ReduxはReactに依存せず、任意のUI層で使用できます。 VueやAngularなどの他のライブラリやフレームワークの場合、Reactの接続関数と同様の機能を提供するバインディングが提供されます。これらのバインディングにより、UIコンポーネントを簡単にReduxストレージに接続し、状態が変更されたときにコンポーネントの更新を処理できます。
反応せずにreduxコードをテストする方法は?
反応なしのreduxコードのテストは、Reactでテストすることに似ています。 JestやMochaなどのJavaScriptテストフレームワークを使用して、アクションクリエイターとリデューサーのユニットテストを作成できます。非同期操作をテストするには、モックストレージを使用してReduxストレージをシミュレートできます。
反応せずにreduxの副作用に対処する方法は?
Reduxの副作用は、通常、Redux ThunkやRedux Sagaなどのミドルウェアを使用して処理されます。これらのミドルウェアを使用すると、副作用やAPI呼び出しなどの複雑な非同期操作を備えた機能をスケジュールできます。反応がなくても、これらのミドルウェアをReduxストレージで使用できます。
純粋なJavaScriptでReduxを使用できますか?
はい、reduxは純粋なJavaScriptで使用できます。 Reduxストアを作成し、アクションをスケジュールし、純粋なJavaScriptのみを使用して州の変更を購読できます。ただし、UIの更新を処理するためのReactのようなライブラリやフレームワークがない場合は、状態が変更されたときにUIコンポーネントを手動で更新する必要があります。
反応せずにreduxコードを構築する方法は?
Reduxコードの構造は、Reactを使用するかどうかに依存しません。操作、還元剤、セレクターの分離、異なるファイルまたはフォルダーに分離したり、正規化されたモジュール式の方法で状態を整理するなど、同じベストプラクティスをReduxコードを構築するための同じベストプラクティスに従うことができます。
反応せずにReduxミドルウェアを使用できますか?
はい、Redux MiddlewareはReactに依存せず、Reduxを使用する任意のUIレイヤーで使用できます。 Reduxのミドルウェアは、副作用や非同期操作などを処理するために使用されます。 ReduxのApplyMiddleware機能を使用して、ReduxのApply MiddlewareをReduxストレージに使用できます。


以上が反応せずにreduxの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

PythonとJavaScriptの主な違いは、タイプシステムとアプリケーションシナリオです。 1。Pythonは、科学的コンピューティングとデータ分析に適した動的タイプを使用します。 2。JavaScriptは弱いタイプを採用し、フロントエンドとフルスタックの開発で広く使用されています。この2つは、非同期プログラミングとパフォーマンスの最適化に独自の利点があり、選択する際にプロジェクトの要件に従って決定する必要があります。

PythonまたはJavaScriptを選択するかどうかは、プロジェクトの種類によって異なります。1)データサイエンスおよび自動化タスクのPythonを選択します。 2)フロントエンドとフルスタック開発のためにJavaScriptを選択します。 Pythonは、データ処理と自動化における強力なライブラリに好まれていますが、JavaScriptはWebインタラクションとフルスタック開発の利点に不可欠です。

PythonとJavaScriptにはそれぞれ独自の利点があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1. Pythonは、データサイエンスやバックエンド開発に適した簡潔な構文を備えた学習が簡単ですが、実行速度が遅くなっています。 2。JavaScriptはフロントエンド開発のいたるところにあり、強力な非同期プログラミング機能を備えています。 node.jsはフルスタックの開発に適していますが、構文は複雑でエラーが発生しやすい場合があります。

javascriptisnotbuiltoncorc;それは、解釈されていることを解釈しました。

JavaScriptは、フロントエンドおよびバックエンド開発に使用できます。フロントエンドは、DOM操作を介してユーザーエクスペリエンスを強化し、バックエンドはnode.jsを介してサーバータスクを処理することを処理します。 1.フロントエンドの例:Webページテキストのコンテンツを変更します。 2。バックエンドの例:node.jsサーバーを作成します。

PythonまたはJavaScriptの選択は、キャリア開発、学習曲線、エコシステムに基づいている必要があります。1)キャリア開発:Pythonはデータサイエンスとバックエンド開発に適していますが、JavaScriptはフロントエンドおよびフルスタック開発に適しています。 2)学習曲線:Python構文は簡潔で初心者に適しています。 JavaScriptの構文は柔軟です。 3)エコシステム:Pythonには豊富な科学コンピューティングライブラリがあり、JavaScriptには強力なフロントエンドフレームワークがあります。

JavaScriptフレームワークのパワーは、開発を簡素化し、ユーザーエクスペリエンスとアプリケーションのパフォーマンスを向上させることにあります。フレームワークを選択するときは、次のことを検討してください。1。プロジェクトのサイズと複雑さ、2。チームエクスペリエンス、3。エコシステムとコミュニティサポート。

はじめに私はあなたがそれを奇妙に思うかもしれないことを知っています、JavaScript、C、およびブラウザは正確に何をしなければなりませんか?彼らは無関係であるように見えますが、実際、彼らは現代のウェブ開発において非常に重要な役割を果たしています。今日は、これら3つの間の密接なつながりについて説明します。この記事を通して、JavaScriptがブラウザでどのように実行されるか、ブラウザエンジンでのCの役割、およびそれらが協力してWebページのレンダリングと相互作用を駆動する方法を学びます。私たちは皆、JavaScriptとブラウザの関係を知っています。 JavaScriptは、フロントエンド開発のコア言語です。ブラウザで直接実行され、Webページが鮮明で興味深いものになります。なぜJavascrを疑問に思ったことがありますか


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

Dreamweaver Mac版
ビジュアル Web 開発ツール

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター
