反应孩子正在通过道具改变父母状态......我不清楚原因
Posted
技术标签:
【中文标题】反应孩子正在通过道具改变父母状态......我不清楚原因【英文标题】:React children are mutating parent state through props...I am unclear as to the cause 【发布时间】: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 之外进行克隆,看看是否是问题所在。
【参考方案1】:
我目前正在做同样的事情。父级将数据作为道具传递给子级函数。 (我使用钩子而不是类)。子组件的目的是处理从父组件提供的数据并导出为 pdf 或 excel。想象一下数据作为一个包含多个对象数组的对象传入。每个子对象都有一个我想删除的 proj id 元素。数据传入的那一刻,我有这个 enter image description here
我使用从父级传入的数据设置状态。当我完成一些过程并删除 projid。当我尝试使用父函数中的任何元素进行访问时。整个事情都坏了。
【讨论】:
以上是关于反应孩子正在通过道具改变父母状态......我不清楚原因的主要内容,如果未能解决你的问题,请参考以下文章