簡単に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の使用例です。

// 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コンポーネントの構築関数を接続オブジェクトとして受け入れ、最終的に接続されたコンポーネント構成関数を返します。
そしていくつかの問題:
  • Reactコンポーネントはどのようにstoreの変化に応答しますか?
  • はどうしてconnectの選択的なmergeのいくつかのprops、直接に全体のstateを入るのではありませんか?
  • pure最適化は何ですか?
  • 私たちはconnectを返した関数をConnectorといいます。それは内部のConnectというコンポーネントです。それは元のコンポーネントを包装した上で、Reduxのstoreの変化を内部でモニターしました。その包装されたコンポーネントがstoreの変化に応答できるようにするために:
    
    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 {
    
    }
    
    
    以上が本文の内容です。皆さんの勉強に役に立つように、私たちを応援してください。