mapDispatchToProps 方法内部的访问状态
Posted
技术标签:
【中文标题】mapDispatchToProps 方法内部的访问状态【英文标题】:Access State inside of mapDispatchToProps method 【发布时间】:2016-06-20 13:31:27 【问题描述】:我使用 redux 编写了一个容器组件,我的 mapDispatchToProps
实现如下所示
const mapDispatchToProps = (dispatch, ownProps) =>
return
onChange: (newValue) =>
dispatch(updateAttributeSelection('genre', newValue));
dispatch(getTableData(newValue, ownProps.currentYear));
问题在于,为了获取表格数据,我需要一些其他组件的状态。如何在此方法中访问状态对象?
【问题讨论】:
【参考方案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
合并 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
大型应用程序可能存在性能缺陷: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());
【讨论】:
以上是关于mapDispatchToProps 方法内部的访问状态的主要内容,如果未能解决你的问题,请参考以下文章
使用 Jest 时是不是有另一种方法来模拟组件的 mapDispatchToProps
使用单个 mapDispatchToProps 的缺点是啥?