【问题标题】:Cannot dispatch in the middle of a dispatch when firing action in child component在子组件中触发操作时无法在调度中间调度
【发布时间】:2016-09-30 20:03:54
【问题描述】:

我目前有我的应用程序结构,因此我有一个 FormWrapper 组件,它为传​​入的 FormName 加载配置,这可能由 React-Router 像这样呈现 -

<Route path="/Diary/Test" components={require('./components/wrapperComponents/formWrapper.jsx')} FormName="AppointmentBooking"/>

当 FormWrapper 加载时,它会调用 ActionCreator 并从服务器获取有关哪个页面的配置,并呈现通过 objProps 传入配置的页面。

render: function() {
    return(React.createElement(PageComponents[this.props.FormName], objProps);
}

这样做的原因是,最初我们希望能够让用户能够轻松地自定义表单的外观以及显示哪些组件,因此它允许我们将表单及其随附的子组件存储在配置中然后使用通用包装器组件将它们加载出来。因此,每个表单通用的任何东西都可以放在表单包装器中,然后表单特定代码可以放在每个页面组件中,并且只加载与该特定页面相关的部分。

我遇到的问题是,如果 AppointmentBooking 表单还需要在 componentWillMount/componentDidMount 方法中触发操作以加载一些数据(例如约会位置下拉列表中的选项),我会收到“无法调度在调度中”错误。

我对这个问题的推理是,由表单包装器触发的初始操作导致重新渲染 formWrapper,因为它随后有数据,然后 React.createElement 试图渲染 AppointmentBooking 组件,该组件也触发了操作从而导致调度程序错误。

我已经阅读了有关使用 waitFor() 在触发第二个操作之前等待第一个操作完成的内容,但这将涉及子组件了解并依赖它的父组件,我认为这可能意味着我没有保持适当的关注点分离。

这是一个常见问题吗?我是否以正确的方式解决这个问题?如果没有,是否有建议的方法来实现这一目标?

【问题讨论】:

  • 你看过redux-thunk和/或redux-saga。首先从redux-thunk 开始。它允许您触发一个动作,该动作本身可以触发多个动作。
  • 感谢您的建议,但我可能应该在帖子中提到我使用的是纯通量而不是 redux。
  • 啊……¯\_(ツ)_/¯ 对不起

标签: javascript reactjs flux reactjs-flux


【解决方案1】:

Flux 最佳实践建议使用“容器”组件,我认为这样做可能会解决您的问题。 https://facebook.github.io/flux/docs/flux-utils.html#best-practices

“容器”组件是一个虚拟组件,其唯一目的是促进商店通信。通过将责任外包给单个组件,您可以解决此类奇怪的种族问题。

容器的基本规则是它们应该始终呈现相同的子组件,同时传递从任何相关商店收集的唯一信息(作为道具)。没有条件逻辑。只是信息的路由。

如果您能够重组为这种范式,它将解决您的问题。但是,如果您的应用程序中已经有动作和侦听器,那么这可不是一件容易的事。

【讨论】:

    猜你喜欢
    • 2016-04-20
    • 2019-10-18
    • 2018-12-10
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    相关资源
    最近更新 更多