Goal :加载react-router路由时,调度Redux操作,请求asynchronic Saga worker获取该路由的基础无状态组件的数据 .
Problem :无状态组件仅仅是函数,并且从函数内部调度Redux动作 .
我的问题部分与Converting stateful React component to stateless functional component: How to implement "componentDidMount" kind of functionality?有关,但我的目标是仅发送一个Redux动作,要求将数据异步填充到商店(我使用Saga,但我认为这与问题无关,因为我的目标是仅发送一个普通的Redux动作),之后由于改变的数据道具,无状态组件将重新渲染 .
我正在考虑两种方法:要么使用react-router的某些功能,要么使用Redux的connect方法 . 是否有一个所谓的"React-way"来实现我的目标?
编辑:到目前为止我唯一提出的解决方案是在mapDispatchToProps中调度动作,这样:
const mapStateToProps = (state, ownProps) => ({
data: state.myReducer.data // data rendered by the stateless component
});
const mapDispatchToProps = (dispatch) => {
// catched by a Saga watcher, and further delivered to a Saga worker that asynchronically fetches data to the store
dispatch({ type: myActionTypes.DATA_GET_REQUEST });
return {};
};
export default connect(mapStateToProps, mapDispatchToProps)(MyStatelessComponent);
然而,这似乎有点脏,而不是正确的方式 .
4 回答
我想我找到了最干净的解决方案,而不必使用有状态组件:
该解决方案将商店传递给更高阶的函数,该函数传递给onEnter生命周期方法 . 从https://github.com/reactjs/react-router-redux/issues/319找到解决方案
一般情况下,如果没有某种触发操作,我认为这是不可能的,当第一次安装/渲染组件时会调度该操作 . 你已经通过使mapDispatchToProps不纯而实现了这一点 . 我100%同意塞巴斯蒂安这是一个坏主意 . 您还可以将杂质移动到渲染功能,这更糟糕 . 组件生命周期方法就是为了这个!如果您不想写出组件类,那么他的HOC解决方案是有意义的 .
我没有太多要补充,但是如果你只是想看到实际的传奇代码,这里有一些伪代码,给出了这样的触发动作(未经测试):
加上样板:
我不知道为什么你绝对想要一个无状态组件,而有一个有组件的动态组件可以用一种简单的方式完成工作 .
mapDispatchToProps
中的调度操作非常危险,并且可能导致不仅在mount时调度,而且每当ownProps或store props更改时都会调度 . 预计这种方法不会产生副作用,应保持纯净 .保持组件无状态的一种简单方法是将其包装到您可以轻松创建的_488934中:
请注意,如果您在此HOC之后使用Redux连接,则可以直接从props直接访问调度,就像您不使用
mapDispatchToProps
一样,注入调度 .然后你可以做一些非常简单的事情:
HOC定义:
以下是您可以执行的操作的简单实现:
如果你在Hello组件周围使用
connect
,你可以将dispatch注入为道具并使用它代替警报消息 .JsFiddle
如果您希望它完全无状态,您可以在使用onEnter事件输入路径时调度事件 .
现在您可以在此处编写函数,前提是您在此文件中导入调度或以某种方式将其作为参数传递 .
But this solution I feel is even more dirty.
另一个我真正高效的解决方案是使用容器并调用componentDidMount .