【问题标题】:reactjs - Why have form value state updated through both parent props and component onChange?reactjs - 为什么通过父道具和组件onChange更新表单值状态?
【发布时间】:2018-10-29 02:25:03
【问题描述】:

我正在阅读 Fullstack React 书籍,在他们关于表单验证的示例中,他们创建了自己的 Field 组件(第 204 - 212 页),然后将字段值存储在 Field 状态和父状态中,这让我很困惑。他们的 Field 组件有一个value 属性以及一个包含value 的状态。父组件需要知道每个字段的值,这样它才能整体做表单验证,所以它也有一个包含value的状态。

在 Field 中,它们通过在输入 value 更改时设置 Field 状态以及在 value 属性更改时使用 getDerivedStateFromProps 来处理 value 更改:

//(within Field)
getDerivedStateFromProps(nextProps) {
     return {value: nextProps.value}
}

onChange = evt => {
    const name = this.props.name;
    const value = evt.target.value;
    const error = this.props.validate ? this.props.validate(value) : false;

    this.setState({value, error});

    this.props.onChange({name, value, error});
};

它们还通过调用父级的 onInputChange 函数(作为 onChange 属性传递)将另一个方向的值状态同步到父级:

//(within parent component)
onInputChange = ({name, value, error}) => {
    const fields = Object.assign({}, this.state.fields);
    const fieldErrors = Object.assign({}, this.state.fieldErrors);

    fields[name] = value;
    fieldErrors[name] = error;

    this.setState({fields, fieldErrors});
};

这本书并没有真正解释他们为什么像这样复制状态,只是说,

"Field 只需要两条数据,当前 价值和错误。就像前面的部分一样,我们的表单组件 它的 render() 方法需要这些数据,我们的 Field 也是如此 组件。”

还有

“一个关键的区别是我们的 Field 有一个父级,有时这 parent 会想要更新我们的 Field 的 value 属性。为了允许这一点, 我们需要创建一个新的生命周期方法, getDerivedStateFromProps() 接受新值并更新 状态。”

我只是一个初学者,但在我看来,在 Field 中完全放弃 value 状态并将其作为道具传入会更有意义。当输入发生变化时,使用 Field 调用 onChange 方法,并在其中调用父级的 onInputChange。让 onInputChange 更新有关字段值的父状态,并将字段值作为道具传递给字段。现在完成的方式似乎有点多余并且更容易出错。任何关于他们为什么这样做的见解?

【问题讨论】:

  • 我完全同意你的看法。他们应该明确地提升状态并保持单一的事实来源。
  • 你一针见血,我能想到的在子组件中复制状态的唯一用例是,如果你试图以某种方式保留原始状态。
  • 唯一的原因是我可以看到这个例子是否继续下去,你必须在此基础上构建,在此基础上解耦子级和父级之间的状态是有意义的。即便如此,它也可能会导致一条混乱的 React 架构之路。我将分享我的两分钱,即使直到今天我还没有阅读过好的 React 教程,甚至没有参加过写得很好的 React 评估测试。我的 React 技能都来自 React 和 Redux 站点本身的示例。
  • @JonasW。谢谢 :) 但是有趣的家伙,我想我以后会看看这样做是否有意义。
  • @josephnvu 到目前为止我很喜欢这本书,所以希望以后它会有意义,或者这只是一个令人困惑的例子:T

标签: javascript forms reactjs


【解决方案1】:

没看过书,这里解释一下为什么要写这样的代码。

拥有这两种状态的主要目的是使Field 组件更通用。

在这种特定情况下,父级恰好也将值保存在其状态中,并且Field 组件通过在getDerivedStateFromProps 上从收到的props 更新其状态来成为受控组件。

但是仍然有可能将Field 组件用作不受控制的组件,那么Field 的状态将是唯一的真实来源。

在这两种情况下,只有一个事实来源,它保持了 React 的做事方式,但是 Field 组件可以以受控和不受控的形式使用。

【讨论】:

  • 啊,好吧。这很有意义。他们之前讨论过将他们的输入形式从不受控制(使用 ref)转换为受控组件,以及他们如何不真正推荐不受控制的。但我猜他们在这里是这样做的,所以它仍然可以不受控制地工作。
猜你喜欢
  • 2015-12-02
  • 2019-04-17
  • 1970-01-01
  • 2019-01-28
  • 2016-11-03
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
  • 2019-09-20
相关资源
最近更新 更多