久々に案件で触るので復習
Provider
指定したコンポーネントがどのstoreを使用するか決める。
多くのケースでは、ルート階層のコンポーネントをProviderでラップして、そことstoreを紐づけている。
(その下のコンポーネントでstoreを参照することができる)
Connect
各コンポーネント単位でどのstoreを参照してどのアクションをdispatchするか決めている。
(コンポーネントを指定する形で使用する)
メリットは以下
- ルート階層以下のコンポーネントでのstoreバケツリレーを防げる
- Providerでラップされたコンポーネントしかstoreを知れないので下階層はバケツリレーするしかないらしい?(曖昧)
- storeのstateの値を変更できるコンポーネントを制限できて保守性をUPできる
connectを使う上で必要な概念が二つ
mapStateProps
connectで指定したコンポーネントで、どのstateを使用するか決める。
こんな感じ
const mapStateProps = ({ count }) => ({ count });
以下の略でこう記述できる
const mapStateProps = state => {
return { count: state.count };
};
mapDispatchProps
connectで指定したコンポーネントで、どのActionをdispatchするか決める。
アクションを実行する役割のdispatch関数を作成している。
const mapDispatchProps = dispatch => ({
increment: count => {
dispatch(increment(count));
},
decrement: count => {
dispatch(decrement(count));
}
});
connectはこんな感じで使う。
指定したコンポーネントで、mapDispatchPropsで定義したdispatch関数やmapStatePropsで指定したstateを、propsとして受け取ることができる。
connect(
mapStateProps,
mapDispatchProps
)(Component);
contaienr
ロジックに責任を持つコンポーネントのこと
containerでmapStatePropsやらmapDispatchPropsやらconnectをまとめることが多い
import { connect } from "react-redux";
import { increment, decrement } from "../../redux/count/actions";
import Counter from "./presentation";
const mapStateProps = ({ count }) => ({ count });
const mapDispatchProps = dispatch => ({
increment: count => {
dispatch(increment(count));
},
decrement: count => {
dispatch(decrement(count));
}
});
export default connect(
mapStateProps,
mapDispatchProps
)(Counter);
presentational
表示にだけ責任を持つコンポーネントのこと
こんな感じで、dispatch関数やstateをpropsで受け取ることができる。
import React from "react";
const Counter = ({ count, increment, decrement }) => (
<>
<div>{count}</div>
<button onClick={() => increment(1)}>+</button>
<button onClick={() => decrement(1)}>-</button>
</>
);
export default Counter;