簡単にReactとReduxの接続react-reduxを話します。
4434 ワード
以前はReact関連のものを探していましたが、手にSPAプロジェクトがありますので、Reduxで水を試してみます。Redux自体とReactは関連していません。ユニバーサルJavscript Appモジュールで、App Stateの管理をしています。ReactのプロジェクトでReduxを使うには、react-reduxというライブラリを使って接続するという意味です。ここでは、react-reduxがないわけではなく、この二つのライブラリを一緒に使うのではなく、react-reduxがパッケージを提供しています。より科学的なコード組織方式で、ReactのコードにReduxを使うのがより快適になります。
以前はRedux文書だけでreact-reduxを理解していましたが、しばらくの間実践した後、ソースコードをひっくり返して、ついでに関連の総括をします。コードのnpmバージョンはv 4.0.0です。つまり使っているReactバージョンは0.14 xです。
react-reduxは2つのキーモジュールを提供します。Providerとconnect。
プロバイダー
Providerというモジュールは、App全体の容器として、既存のApp Continerをベースにもう一つの層を包む作業が簡単で、Reduxのstoreをpropsとして受け入れ、その声明をcontextの属性の一つとして、サブアセンブリはcontextTypesを宣言した後に、this.comを通じてstoreにアクセスすることができます。でも、私達のコンポーネントは通常このようにする必要がなくて、storeをcontextの中に置いて、下のconnectに使うためです。
これはProviderの使用例です。
このモジュールは本当の意味でReduxとReactを接続しています。ちょうどその名前もconnectです。
先にReduxがどのように動作するかを考えます。まずstoreでstateを維持しました。私たちはdispatchでactionを作りました。これからreducerはこのactionによってstateを更新します。
私たちのReactアプリケーションにマッピングされ、storeでメンテナンスされているstateは私たちのap stateであり、ReactコンポーネントはView層として、二つのことをします。そこでconnectは、storeに必要なデータをpropsとしてReactコンポーネントに伝達し、action creatorを包装して、ユーザの操作に応答する時にdispatchの一つのactionに用いる。
はい、connectというモジュールは何をしていますか?まず、その使用から言えば、APIは以下の通りである。
mergopsはカスタムmergeプロセスに使用されます。これはデフォルトの流れです。parentProps値はコンポーネント自体のpropsです。コンポーネントのpropsに同名があれば、上書きされます。
connectは、Reactコンポーネントの構築関数を接続オブジェクトとして受け入れ、最終的に接続されたコンポーネント構成関数を返します。
そしていくつかの問題: Reactコンポーネントはどのようにstoreの変化に応答しますか? はどうしてconnectの選択的なmergeのいくつかのprops、直接に全体のstateを入るのではありませんか? pure最適化は何ですか? 私たちはconnectを返した関数をConnectorといいます。それは内部のConnectというコンポーネントです。それは元のコンポーネントを包装した上で、Reduxのstoreの変化を内部でモニターしました。その包装されたコンポーネントがstoreの変化に応答できるようにするために:
具体的に最適化された方法は、shuldComponentUpdateで検査を行い、コンポーネント自体のpropsが変更された場合や、mapStateToPropsの結果が変更された場合、またはmapDisplatToPropsの結果が変わった時にshuldComponentUpdateがtrueに戻り、検査の方式はshorwEqualの比較を行います。
したがって、あるreducerにとって:
最後に、connectのAPIによって、ES 7 decorator機能を使ってReact ES 6の書き方に協力できることを発見しました。
以前はRedux文書だけでreact-reduxを理解していましたが、しばらくの間実践した後、ソースコードをひっくり返して、ついでに関連の総括をします。コードのnpmバージョンはv 4.0.0です。つまり使っているReactバージョンは0.14 xです。
react-reduxは2つのキーモジュールを提供します。Providerとconnect。
プロバイダー
Providerというモジュールは、App全体の容器として、既存のApp Continerをベースにもう一つの層を包む作業が簡単で、Reduxのstoreをpropsとして受け入れ、その声明をcontextの属性の一つとして、サブアセンブリはcontextTypesを宣言した後に、this.comを通じてstoreにアクセスすることができます。でも、私達のコンポーネントは通常このようにする必要がなくて、storeをcontextの中に置いて、下のconnectに使うためです。
これはProviderの使用例です。
// config app root
const history = createHistory()
const root = (
<Provider store={store} key="provider">
<Router history={history} routes={routes} />
</Provider>
)
// render
ReactDOM.render(
root,
document.getElementById('root')
)
プロジェクトこのモジュールは本当の意味でReduxとReactを接続しています。ちょうどその名前もconnectです。
先にReduxがどのように動作するかを考えます。まずstoreでstateを維持しました。私たちはdispatchでactionを作りました。これからreducerはこのactionによってstateを更新します。
私たちのReactアプリケーションにマッピングされ、storeでメンテナンスされているstateは私たちのap stateであり、ReactコンポーネントはView層として、二つのことをします。そこでconnectは、storeに必要なデータをpropsとしてReactコンポーネントに伝達し、action creatorを包装して、ユーザの操作に応答する時にdispatchの一つのactionに用いる。
はい、connectというモジュールは何をしていますか?まず、その使用から言えば、APIは以下の通りである。
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
mapStation ToPropsは関数であり、戻り値はpropsのstateにmergeを進める必要があることを表しています。標準値は()=>({})で、何も伝えません。
(state, props) => ({ }) //
mapDisplatch ToPropsは関数でもいいです。戻り値はpropsのactionCreatorsだけが必要です。ここのactionCreatorはdispatchを包装したはずです。reduxのbindActures関数を使うことを勧めます。
(dispatch, props) => ({ //
...bindActionCreators({
...ResourceActions
}, dispatch)
})
より便利なのは、オブジェクトを直接受け入れることができます。このとき、connect関数内部では関数に変換されます。この関数は上記の例と同じです。mergopsはカスタムmergeプロセスに使用されます。これはデフォルトの流れです。parentProps値はコンポーネント自体のpropsです。コンポーネントのpropsに同名があれば、上書きされます。
(stateProps, dispatchProps, parentProps) => ({
...parentProps,
...stateProps,
...dispatchProps
})
optionsは全部で二つのスイッチがあります。pureは最適化を開くかどうかを表しています。詳細は以下に述べます。デフォルトはtrue、withRefは中に包装されているコンポーネントにrefを与えます。getWrapped Instance方法でこのrefを取得できます。デフォルトはfalseです。connectは、Reactコンポーネントの構築関数を接続オブジェクトとして受け入れ、最終的に接続されたコンポーネント構成関数を返します。
そしていくつかの問題:
trySubscribe() {
if (shouldSubscribe && !this.unsubscribe) {
this.unsubscribe = this.store.subscribe(::this.handleChange)
this.handleChange()
}
}
handleChange () {
this.setState({
storeState: this.store.getState()
})
}
しかし、通常、私達のconnectのはあるContactainerコンポーネントで、それはすべてのApp stateを積載していません。しかし、私達のhandlerはすべてのstateの変化に応答しています。そこで、私達は最適化が必要です。storaStateが変化する時、私達が本当にその部分に依存しているだけで、Reactコンポーネントは何が本当に依存していますか?mapStateToPropsとmapDisplatToPropsで得られました。具体的に最適化された方法は、shuldComponentUpdateで検査を行い、コンポーネント自体のpropsが変更された場合や、mapStateToPropsの結果が変更された場合、またはmapDisplatToPropsの結果が変わった時にshuldComponentUpdateがtrueに戻り、検査の方式はshorwEqualの比較を行います。
したがって、あるreducerにとって:
export default (state = {}, action) => {
return { ...state } // , reRender
// return state // reRender
}
また、connectでは、mapが本当に必要とするstateまたはactionCreatorsをpropsに慎重にし、不必要な性能損失を避ける。最後に、connectのAPIによって、ES 7 decorator機能を使ってReact ES 6の書き方に協力できることを発見しました。
@connect(
state => ({
user: state.user,
resource: state.resource
}),
dispatch => ({
...bindActionCreators({
loadResource: ResourceActions.load
}, dispatch)
})
)
export default class Main extends Component {
}
以上が本文の内容です。皆さんの勉強に役に立つように、私たちを応援してください。