我有一个非常简单的 react 示例。父组件通过props
将数据传递给子组件。在子组件内部,我可以更改此数据,也可以随时将新数据从父组件传递到子组件。另外,在父级上我有保存按钮。按下它后,如果某些验证未通过,我应该显示验证消息。
我是按照这样的方式实现的。我从父级传递回调来通知父级数据的有效性已更改。在 child 内部,我在三个地方执行验证:
componentDidMount
- 验证初始数据componentWillReceiveProps
- 验证可以从父级传递的数据onChange
验证输入的数据 每当 child 执行数据验证时,我都会调用回调来通知 parent 有效性。问题出在componentWillReceiveProps
中。在父级中使用 setState 时,这部分会导致无限循环 - 参见下图。 请查看jsfiddle在控制台中,您可以看到我将无限循环限制为 10 次迭代,以防止浏览器崩溃。
正如你所看到的,存在无限循环 - 因为 React 以不太聪明的方式调用 componentWillReceiveProps
- 每个渲染周期而不是仅在 props 实际更改时才调用它。
我真的很想知道解决这个问题的 react 方式是什么。我应该只将子状态存储在 child 中吗?我还尝试将 child 有效性存储在州外的 parent 中 - 但我的同事说这不是 react 方式 - 为什么?
最佳答案
以下是我对您面临的挑战的看法:
- 您希望在子组件中使用验证方法,因为它特定于此类子组件(例如密码输入字段)。 - 但在react中,任何外部组件(除了孙子组件)都不允许直接调用此方法。
- 您希望您的父组件了解每个子组件的有效性(例如,确定所有字段均已验证并允许表单提交) - 因此您需要父组件中验证方法的结果,并且这必须是状态
你的同事是正确的:react 不喜欢你在状态之外存储组件范围的变量。因为这些变量完全独立于 React 生命周期方法等,并且会让你很快陷入调试 hell 。
我建议您进行以下更改以防止无限循环:
- 不要将子项的有效性存储在子项状态中。将结果+任何消息保存在父级中,并将其作为 Prop 传递给子级。 child 只渲染 Prop 。
- 实现
shouldComponentUpdate()
,它检查任何 props 或状态变量是否已更改。如果不是返回false
,否则返回true
。 - 将对
validate()
的调用从componentWillReceiveProps
移至componentWillUpdate()
。这在shouldComponentUpdate()
之后调用。因此,只有当 props 或子状态发生变化时,才会进行验证(和重新渲染)。
关于javascript - 如何在react.js中执行子组件验证而无需无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37441407/