react-reduxを使ってみる

React Redux is the official React binding for Redux. It lets your React components read data from a Redux store, and dispatch actions to the store to update data.

Reactコンポーネントが、Reduxの管理するストアからデータを読み、ストアに向けてアクションを発行してデータを更新することが出来るようになる。

react-redux.js.org

以下、定型文的サムシング🦸‍♀️

$ npm install redux react-redux

キモは、Providerとconnect。

ReactコンポーネントからActionをdispatchするにはStoreが必要だが、コンポーネントが大量かつ階層も深くなってくると、最上位からStoreを行き渡らせるのは大変になってくる。そこでProviderの仕組みを使って、connect関数で任意のコンポーネントとStoreの紐付けを行う。

こんな感じ。ContainerComponentを挟んでいるのがポイント。

index.js

import React from 'react';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import { render } from 'react-dom';
import tasksReducer from './reducers/tasks';
import SomeCoolApp from './containers/SomeCoolApp';

const store = createStore(tasksReducer);

render(
  <Provider store={store}>
    <SomeCoolApp />
  </Provider>,
  document.getElementById("root")
);

ContainerComponentでは、stateの値やdispatchを実行する関数など、Propsとして渡したいものを準備する。そして、connectを使って紐付け。

mapStateToProps = Storeから使いたいstateを選び、オブジェクトに入れて返す。
mapDispatchToProps = コンポーネントから見た際、dispatch処理を意識させないで(隠蔽して)実行できるようにする。

containers/SomeCoolApp.js

import { connect } from 'react-redux';
import SomeCoolApp from '../components/SomeCoolApp';
import { addTask } from '../actions/tasks';

function mapStateToProps({ task, tasks }) {
  return { task, tasks };
}

function mapDispatchToProps(dispatch) {
  return {
    addTask(task) {
      dispatch(addTask(task))
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(SomeCoolApp);

んで、Presentational ComponentにPropsとして渡ってくると。

export default function SomeCoolApp({ task, tasks, addTask }) {
...

こうやって省略して書くのもアリ

export default connect(
  state => ({
    sandwiches: state.sandwiches
  })
)(SandwichShop);