[解決済み】Reactアプリケーションにサービスを持たせる
質問
私は、サービス/ファクトリーにロジックを抽出し、それらを私のコントローラで消費することができたangularの世界から来ました。
Reactアプリケーションで同じことを実現するにはどうしたらいいのか、理解しようとしています。
例えば、ユーザーのパスワード入力(強度)を検証するコンポーネントがあるとします。このロジックはかなり複雑なので、コンポーネント自体にそれを書きたくはありません。
このロジックはどこに書けばいいのでしょうか?fluxを使っているならば、ストアの中に?それとも、もっといい方法があるのでしょうか?
どのように解決するのですか?
最初の回答は、現在の コンテナとプレゼンターの比較 のパラダイムがあります。
パスワードの検証のようなことをする必要がある場合、おそらくそれを行う関数を持っていることでしょう。 その関数をプロップとして再利用可能なビューに渡すことになります。
コンテナ
つまり、正しい方法は、その関数をプロパティとして持つ ValidatorContainer を書き、その中にフォームをラップして、正しいプロップを子に渡すことです。 ビューでは、バリデータコンテナがビューをラップし、ビューがコンテナのロジックを消費します。
バリデーションはすべてコンテナのプロパティで行うこともできますが、サードパーティのバリデータや簡単なバリデーションサービスを使用している場合は、そのサービスをコンテナコンポーネントのプロパティとして使用し、コンテナのメソッドで使用することができます。 私はこれをrestfulコンポーネントに対して行いましたが、非常にうまくいきました。
プロバイダー
もう少し設定が必要な場合は、Provider/Consumerモデルを使用することができます。 プロバイダとは、トップアプリケーションオブジェクト(マウントするオブジェクト)のどこか近くや下に回り込んで、自身の一部やトップレイヤーで設定したプロパティをコンテキストAPIに供給する上位コンポーネントである。 そして、コンテナ要素を設定して、コンテキストを消費させる。
コンテキストの親子関係は、近くにある必要はなく、ただ、子が何らかの形で降臨している必要がある。 ReduxのストアとReact Routerは、このような機能を備えています。 私は、(自分で提供しない場合)自分のレストコンテナのルートレストフルコンテキストを提供するために、これを使用している。
(注:コンテキストAPIはドキュメントでは実験的と記されているが、使っているものを考えると、もうそうではないと思う)。
//An example of a Provider component, takes a preconfigured restful.js
//object and makes it available anywhere in the application
export default class RestfulProvider extends React.Component {
constructor(props){
super(props);
if(!("restful" in props)){
throw Error("Restful service must be provided");
}
}
getChildContext(){
return {
api: this.props.restful
};
}
render() {
return this.props.children;
}
}
RestfulProvider.childContextTypes = {
api: React.PropTypes.object
};
ミドルウェア
さらに、私は試していませんが、使われているのを見たことがあるのが、Reduxと組み合わせてミドルウェアを使用する方法です。 サービスオブジェクトをアプリケーションの外、少なくともreduxストアよりも上位に定義します。 ストアの作成時に、サービスをミドルウェアにインジェクトし、ミドルウェアはサービスに影響を与えるすべてのアクションを処理します。
このように、restful.jsオブジェクトをミドルウェアに注入し、コンテナのメソッドを独立したアクションに置き換えることができます。 フォームビューレイヤーにアクションを提供するためのコンテナコンポーネントがまだ必要ですが、connect()とmapDispatchToPropsでカバーできます。
新しいv4のreact-router-reduxは、このメソッドを使って、例えば履歴の状態に影響を与えることができます。
//Example middleware from react-router-redux
//History is our service here and actions change it.
import { CALL_HISTORY_METHOD } from './actions'
/**
* This middleware captures CALL_HISTORY_METHOD actions to redirect to the
* provided history object. This will prevent these actions from reaching your
* reducer or any middleware that comes after this one.
*/
export default function routerMiddleware(history) {
return () => next => action => {
if (action.type !== CALL_HISTORY_METHOD) {
return next(action)
}
const { payload: { method, args } } = action
history[method](...args)
}
}
関連
-
[解決済み] configuration.module に未知のプロパティ 'loaders' があります。
-
[解決済み] componentDidUpdate'メソッドはいつ使用するのですか?
-
[解決済み] Reactルータを使ったプログラムによるナビゲーション
-
[解決済み] React JSX内のループ
-
[解決済み] Reactのこの3つの点は何をするところなのでしょうか?
-
[解決済み] React-routerのURLを更新したり、手動で書き込んだりするとうまくいかない
-
[解決済み] React NativeとReactの違いは何ですか?
-
[解決済み] setStateを呼び出さずにReactコンポーネントを強制的に再レンダリングすることは可能ですか?
-
[解決済み] Reactコンポーネントに条件付きで属性を追加するにはどうすればよいですか?
-
[解決済み] React jsのonClickはメソッドに値を渡すことができない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エラー: 未定義のプロパティ 'map' を読み取ることができません。
-
[解決済み】React 17で動作するEnzymeアダプターはどれですか?
-
[解決済み】ngrokがReact devサーバーに接続しようとすると、無効なホストヘッダが表示される。
-
[解決済み] Jestの `beforeEach` グローバルは何のためにあるのですか?
-
[解決済み] マテリアルUIセレクトフィールドのマルチセレクト
-
[解決済み] formcontrollabel - material-ui | Reactのデフォルトのtypography classを変更するには?
-
[解決済み] Webpack のコンパイルに失敗した
-
[解決済み] sh: react-scripts: npm start の実行後にコマンドが見つからない。
-
[解決済み] react.jsでng-ifに相当するものは何ですか?
-
[解決済み] React JSでは、状態を直接変異させない、setState() react/no-direct-mutation-stateを使用する。