小编典典

在 React Form 中更新 props 更改的状态

all

我在使用 React 表单和正确管理状态时遇到问题。我在表单中有一个时间输入字段(在模式中)。初始值设置为
中的状态变量getInitialState,并从父组件传入。这本身就可以正常工作。

当我想通过父组件更新默认的 start_time 值时,问题就来了。更新本身通过setState start_time: new_time.
但是在我的表单中,默认start_time值永远不会改变,因为它只在getInitialState.

我试图通过componentWillUpdate强制改变状态setState start_time: next_props.start_time,这确实有效,但它给了我Uncaught RangeError: Maximum call stack size exceeded错误。

所以我的问题是,在这种情况下更新状态的正确方法是什么?我在想这个错误吗?

当前代码:

@ModalBody = React.createClass
  getInitialState: ->
    start_time: @props.start_time.format("HH:mm")

  #works but takes long and causes:
  #"Uncaught RangeError: Maximum call stack size exceeded"
  componentWillUpdate: (next_props, next_state) ->
    @setState(start_time: next_props.start_time.format("HH:mm"))

  fieldChanged: (fieldName, event) ->
    stateUpdate = {}
    stateUpdate[fieldName] = event.target.value
    @setState(stateUpdate)

  render: ->
    React.DOM.div
      className: "modal-body"
      React.DOM.form null,
        React.createElement FormLabelInputField,
          type: "time"
          id: "start_time"
          label_name: "Start Time"
          value: @state.start_time
          onChange: @fieldChanged.bind(null, "start_time")

@FormLabelInputField = React.createClass
  render: ->
    React.DOM.div
      className: "form-group"
      React.DOM.label
        htmlFor: @props.id
        @props.label_name + ": "
      React.DOM.input
        className: "form-control"
        type: @props.type
        id: @props.id
        value: @props.value
        onChange: @props.onChange

阅读 68

收藏
2022-06-07

共1个答案

小编典典

componentWillReceiveProps 自反应 16
以来已被贬低:改用getDerivedStateFromProps

如果我理解正确,您有一个父组件正在传递start_time给将ModalBody其分配给自己状态的组件?并且您想从父组件而不是子组件更新该时间。

React
有一些处理这种情况的技巧。
(注意,这是一篇旧文章,已从网络上删除。这是组件道具上当前文档的链接)。

使用 props
生成状态getInitialState通常会导致重复“真相来源”,即真实数据所在的位置。这是因为getInitialState仅在首次创建组件时调用。

只要有可能,即时计算值,以确保它们以后不会不同步并导致维护麻烦。

基本上,每当您将父级分配给props子级时state,并不总是在道具更新时调用渲染方法。您必须使用该componentWillReceiveProps方法手动调用它。

componentWillReceiveProps(nextProps) {
  // You don't have to do this check first, but it can help prevent an unneeded render
  if (nextProps.startTime !== this.state.startTime) {
    this.setState({ startTime: nextProps.startTime });
  }
}
2022-06-07