我在使用 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
errors.
所以我的问题是,在这种情况下更新状态的正确方法是什么?我是否以某种方式思考这个错误?
当前代码:
@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
自 React 16 起,ComponentWillReceiveProps 已被弃用:使用从Props获取DerivedState https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops instead
如果我理解正确的话,你有一个正在传递的父组件start_time
下降到ModalBody
将其分配给自己的状态的组件?并且您希望从父组件而不是子组件更新该时间。
React 有一些处理这种情况的技巧。 https://web.archive.org/web/20170101062930/http://reactjs.cn/react/tips/props-in-getInitialState-as-anti-pattern.html(请注意,这是一篇旧文章,已从网络上删除。这是当前文章的链接组件 props 的文档 https://reactjs.org/docs/components-and-props.html).
使用 props 生成状态getInitialState
通常会导致“事实来源”的重复,即真实数据的位置。这是因为getInitialState
仅在首次创建组件时调用。
只要有可能,即时计算值,以确保它们以后不会不同步并导致维护麻烦。
基本上,每当你分配父母的props
到一个孩子的state
render 方法并不总是在 prop 更新时调用。您必须使用以下命令手动调用它componentWillReceiveProps
method.
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 });
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)