我知道这个问题可能听起来重复,但我没有找到任何好的解决方案,特别是与reselect结合使用。
请考虑遵循redux容器组件:
export default connect((state, props) => {
return {
...props
}
}, (dispatch) => {
if (shouldLoadClinic(store.getState())) {
dispatch(loadClinicInfo())
}
if (shouldLoadTimezones(store.getState())) {
dispatch(loadTimezones())
}
return {}
})(SettingsClinic)
例如。 shouldLoadClinic()定义如下:
import { createSelector } from 'reselect'
export const isClinicLoaded = ({ clinic }) => {
return clinic.current !== null
}
export const isClinicLoading = ({ clinic }) => {
return clinic.pending
}
export const shouldLoadClinic = createSelector([
isClinicLoaded,
isClinicLoading
], (isLoaded, isLoading) => {
return !isLoaded && !isLoading
})
此组件应确保其子组件已获得所有必需的数据。 我不喜欢这个解决方案的几个原因:
外部范围需要getState()(将getState prop与“dispatch”arg一起传递会很高兴。)
难以测试 - 为了测试数据是否在mount上加载我将不得不模拟存储,选择器和操作。
你有什么想法吗?也许只是与参考文献的链接就足够了。
提前致谢。
答案 0 :(得分:0)
connect
(mergedProps
)的第3个参数来访问stateProps和dispatchProps,这样就可以使用selectors
内的mapStateToProps
然后使用结果在mergedProps
中 - dispatch
相同。另一种方法是使用redux-thunk
中间件,这样,您可以随时调度要加载的操作,并在ifNeeded
中检查thunk
。 p.s:我真的不喜欢你在mapDispatchToProps
做的猴子补丁。最好总是返回一个加载数据的函数,并在组件的componentDidMount
内调用它,或者在HOC中一起加载数据。
我的意思是改变这个:
if (shouldLoadClinic(store.getState())) {
dispatch(loadClinicInfo())
}
if (shouldLoadTimezones(store.getState())) {
dispatch(loadTimezones())
}
return {}
这样的事情:
return {
loadData: () => {
dispatch(loadClinicInfo());
dispatch(loadTimezones());
}
}
最后的注释,here是我创建的HOC的一个小小的要点,用于处理数据并在执行时显示加载程序。希望它有所帮助。
以下是connect的第三个参数mergedProps
:
const mapStateToProps = state => ({someData: selectSomeData(state)});
const mapDispatchToProps = dispatch => ({dispatch})
const mergedProps = (stateProps, dispatchProps) => {
return {
loadData: () => stateProps.someData
? dispatchProps.loadData()
: null
}
}
connect(mapStateToProps, mapDispatchToProps, mergedProps)(Component)