Reduxを使用してコンテナコンポーネントを作成しました。mapDispathToPropsの実装は次のようになります。
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onChange: (newValue) => {
dispatch(updateAttributeSelection('genre', newValue));
dispatch(getTableData(newValue, ownProps.currentYear));
}
}
}
問題は、getTableDataを取得するために、他のコンポーネントの状態が必要なことです。このメソッドで状態オブジェクトにアクセスするにはどうすればよいですか?
Redux-thunkを使用して、getState
内で関数を定義するのではなく、mapDispatchToProps
にアクセスできる別のアクションクリエーター関数を作成できます。
function doTableActions(newValue, currentYear) {
return (dispatch, getState) => {
dispatch(updateAttributeSelection('genre', newValue));
let state = getState();
// do some logic based on state, and then:
dispatch(getTableData(newValue, currentYear));
}
}
let mapDispatchToProps = (dispatch, ownProps) => {
return {
onChange : (newValue) => {
dispatch(doTableActions(newValue, ownProps.currentYear))
}
}
}
それらを整理するためのさまざまな方法がありますが、そのようなものが機能するはずです。
可能なアプローチは、mergeProps
とmapState
をマージし、両方を同時に使用できるmapDispatch
を使用することです。
// Define mapState
const mapState = (state) => ({
needeedValue: state.neededValue
})
// Define mapDispatch
const mapDispatch = (dispatch, ownProps) => {
return {
onChange: (newValue, neededValue) => {
dispatch(updateAttributeSelection('genre', newValue));
dispatch(getTableData(newValue, ownProps.currentYear, neededValue));
}
}
}
// Merge it all (create final props to be passed)
const mergeProps = (stateProps, dispatchProps, ownProps) => {
return {
...stateProps, // optional
...dispatchProps, // optional
onChangeWithNeededValue: (newValue) => (
dispatchProps.onChange(
newValue,
stateProps.needeedValue // <<< here the magic happens
)
)
}
}
// Pass mergePros to connect
const MyContainer = connect(mapState, mapDispatch, mergeProps)(MyComponent);
公式ドキュメント: react-redux#connect
大きなアプリで起こりうるパフォーマンスの欠点: スタックオーバーフロー-ReduxのパフォーマンスとmergeProps
状態を取得するには、redux-thunkを使用するだけです。次のようなヘルパー関数を作成します。
const getState = (dispatch) => new Promise((resolve) => {
dispatch((dispatch, getState) => {resolve(getState())})
})
これは、非同期関数またはジェネレーター関数で使用できます。
const mapDispatchToProps = (dispatch, ownProps) => {
return {
async someFunction() {
const state = await getState(dispatch)
...
}
}
}
あなたが使用しようとすることができます:
これにより、コードのどこにでも状態を取得できます:
const localState1 = getState(reducerA.state1)
const localState2 = getState(reducerB.state2)
同様にmapDispatchToPropsで:
const mapDispatchToProps = dispatch => {
return {
onClick: () => {
dispatch(someAction(getState(moduleA.state1)));
}
};
};
サンクミドルウェアを使用している場合、ヘルパー関数をAction.Jsに記述できます。
export const getSearchedText = () => (dispatch, getState) => {
const { app } = getState();
return app.searchedText;
}
コンテナデザインパターンを使用している場合、プロパティコンテナは以下のようになります。
Container.js
export const mapDispatchToProps = (dispatch, ownProps) => {
return {
setSearch: search => {
var searchedText = dispatch(getSearchedText());
}
}