web-dev-qa-db-ja.com

mapDispatchToPropsメソッド内のアクセス状態

Reduxを使用してコンテナコンポーネントを作成しました。mapDispathToPropsの実装は次のようになります。

const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        onChange: (newValue) => {
            dispatch(updateAttributeSelection('genre', newValue));
            dispatch(getTableData(newValue, ownProps.currentYear));
        }
    }
}

問題は、getTableDataを取得するために、他のコンポーネントの状態が必要なことです。このメソッドで状態オブジェクトにアクセスするにはどうすればよいですか?

41
Knows Not Much

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))
        }
    }
}

それらを整理するためのさまざまな方法がありますが、そのようなものが機能するはずです。

37
markerikson

可能なアプローチは、mergePropsmapStateをマージし、両方を同時に使用できる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

14
exmaxx

状態を取得するには、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)
      ...
    }
  }
}
4
llwwns

あなたが使用しようとすることができます:

redux-named-reducers

これにより、コードのどこにでも状態を取得できます:

const localState1 = getState(reducerA.state1)
const localState2 = getState(reducerB.state2)

同様にmapDispatchToPropsで:

const mapDispatchToProps = dispatch => {
  return {
    onClick: () => {
      dispatch(someAction(getState(moduleA.state1)));
    }
  };
};
1
miles_christian

サンクミドルウェアを使用している場合、ヘルパー関数を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());
             }
}
1
Hamit YILDIRIM