【发布时间】:2016-08-22 11:45:52
【问题描述】:
我有一个 React 组件,它将一个对象传递给一个包含要通过传递函数修改的输入字段的子元素。输入字段正在更改子元素的状态,但不知何故,在不调用传递的函数的情况下,props 对象正在被修改。
这是父类的渲染函数:
render: function() {
const newTriggerClass = this.state.item.triggerID === ""
? " new-trigger"
: "";
return (
<div className={newTriggerClass}>
<div className="triggers-detail">
<section className="trigger-info group">
<TriggerInfoEntry
item={this.state.item}
triggerState={this.state.editTriggerState}
columnHeaders={this.props.columnHeaders}
hideDetail={this.hideDetail}
editAction={this.props.editAction}
editToggle={this.editToggle}
_onChange={this._onInfoChange}
createAction={this.props.createAction}
deleteAction={this.props.deleteAction}/>
</section>
<section className="trigger-actions group">
<TriggerActionEntry
item={this.state.item}
actionState={this.state.editActionState}
editToggle={this.editToggle}
editAction={this.editTriggerAction}
actionIndex={this.state.selectedActionIndex}/>
</section>
</div>
<div className={"modal-overlay" + newTriggerClass}>
</div>
</div>
);
},
子 TriggerActionEntry 将它自己的 state.item 设置为 props.item 的克隆。
propTypes: {
item: React.PropTypes.object.isRequired,
editAction: React.PropTypes.func.isRequired,
editToggle: React.PropTypes.func.isRequired,
actionState: React.PropTypes.bool
},
getInitialState: function() {
return {
item: assign({testy: true}, this.props.item),
actionIndex: 0,
deleteState: false,
editState: false
};
},
当我通过输入更改子组件 (state.item) 的状态时,父状态会更改!我不确定原因。我在网上阅读的任何内容都没有暗示这种行为。任何帮助表示赞赏。
更新:
@garrettmaring 我用来更改状态的代码仅设计用于在 getInitialState 中设置为this.props.item 到assign 的克隆的子状态,这是我的别名object-assign 这是Object.assign ponyfill .更改item 的表格实际上是多了一个孩子。这是TriggerActionEntry的渲染图
<div>
<TriggerActionForm
action={this.state.item.actions[this.state.actionIndex]}
index={this.state.actionIndex}
addNewAction={this.addNewAction}
editTriggerAction={this.editTriggerAction}
deleteTriggerAction={this.deleteTriggerAction}
editState={this.state.editState}
deleteState={this.props.actionState}
toggleEdit={this.toggleEdit}
activateEdit={this.activateEdit}/>
</div>
这里是孙子TriggerActionForm的_onChange函数
_onChange: function (e) {
e.preventDefault();
let newAction = assign({}, this.state.action);
const keyname = e.currentTarget.dataset.keyname;
if (keyname === "minDelay") {
newAction[keyname] = e.currentTarget.value;
} else {
newAction.args[keyname] = e.currentTarget.value;
}
this.setState({action: newAction});
if (!this.props.editState) {
this.props.activateEdit();
}
},
即使我卸载该组件,TriggerActionEntry state.item 也会被修改,并在再次安装组件时显示为修改状态...
更新 2:好的,问题是 Object.assign 和 object-assign 都没有深度克隆对象。经典!这些操作是嵌套在item 中的对象,而不是被克隆,而是创建了对嵌套对象的另一个引用。谢谢大家的帮助。
【问题讨论】:
-
嗯,你在
getInitialState函数中试过Object.assign({}, {testy: true}, this.props.item)吗?或者在传递之前创建this.state.item的克隆。这似乎是一个参考问题。也就是说,即使你在getInitialState中使用了assign,子组件中的item仍然持有对父组件中state.item的引用。 -
@suntruth 向我们展示您在子元素上使用
setState的代码。似乎您正在更改对象的属性,如果这是真的,它与父元素具有的对象引用相同,因此它也会更改。如果要为项目设置新状态,则应在使用setState时完全创建一个新对象,不仅对项目使用assign,还对整个对象使用assign。 -
@garrettmaring,我在问题中添加了更多细节。感谢您的回复
-
我会尝试在 getInitialState 之外进行克隆,看看是否是问题所在。
标签: object reactjs properties state children