【问题标题】:Access State inside of mapDispatchToProps methodmapDispatchToProps 方法内部的访问状态
【发布时间】:2016-06-20 13:31:27
【问题描述】:

我使用 redux 编写了一个容器组件,我的 mapDispatchToProps 实现如下所示

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

问题在于,为了获取表格数据,我需要一些其他组件的状态。如何在此方法中访问状态对象?

【问题讨论】:

    标签: redux react-redux


    【解决方案1】:

    你可以使用 redux-thunk 创建一个单独的 action creator 函数来访问 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))
            }
        }
    }
    

    一些不同的方式来组织这些,但类似的东西应该有效。

    【讨论】:

    • 我认为在 mapDispatchToProps 中访问状态的真正用例是知道哪些操作在运行时可用。例如,您可以将每个可能的操作映射到一个函数并调用它来调度该操作或使用 if 子句对其进行测试以检查该操作是否可用。
    • 在我看来,做这么简单的事情太复杂了。
    【解决方案2】:

    你可以只使用 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)
          ...
        }
      }
    }
    

    【讨论】:

      【解决方案3】:

      可能的方法也是使用 mergeProps 合并 mapStatemapDispatch 并允许同时使用两者。

      // 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

      大型应用程序可能存在性能缺陷:Stack Overflow - Performances and mergeProps in Redux

      【讨论】:

      • 此解决方案还将onChange 传递给MyComponent。如果您只想传递onChangeWithNeededValue,则必须排除此道具。
      【解决方案4】:

      你可以尝试使用:

      redux-named-reducers

      这使您可以像这样在代码中的任何位置获取状态:

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

      mapDispatchToProps 也是如此:

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

      【讨论】:

        【解决方案5】:

        如果您使用过 Thunk 中间件,那么您可以将辅助函数写入您的 Action.Js

        export const getSearchedText =  () => (dispatch, getState) => {
            const { app } = getState();
            return app.searchedText;
        }
        

        如果你用过容器设计模式,你的属性容器应该在下面

        容器.js

        export const mapDispatchToProps = (dispatch, ownProps) => {
            return {
                     setSearch: search => {
                         var searchedText = dispatch(getSearchedText());
                     }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-03-24
          • 2019-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多