保持对特定(或“活动”)对象的引用是我在许多情况下使用的模式,用于更改对象数组中的特定对象(或者你有什么)。
state = {
object1: { 'data': 'data1'},
active_object: null,
}
// point active_object to object1
state.active_object = state.object1;
// modify it through the reference
state.active_object.data = 'data1modified';
// works as expected
console.log('object1.data: ' + state.object1.data);
现在反应组件状态中的等价物将沿着这些线(注意这是非工作的)。我认为引用会在“翻译的某个地方”丢失。是否有(简单)方式来模仿上面的模式(除了重组,使用对象键等)使用react和state来完成同样的事情?
class App extends Component {
constructor() {
super()
this.state = {
active_object: null,
object1: { 'data': 'data1'},
}
}
modifyState() {
// point active_object to object1 (using *functional* setState)
this.setState((state) => (
{ active_object: state.object1 }
))
// modify it through the reference (using *functional* setState)
this.setState((state) => (
{ active_object: { ...state.active_object, ['data']: 'data1modified' } }
))
}
render() {
return (
<div className="App">
<p onClick={ () => this.modifyState() }>modify</p>
<p>{ this.state.object1.data }</p>
</div>
);
}
}
编辑:我已经更新了示例,使用构造函数来混淆人们(我正在使用babel,所以现实中并不需要)。另外,我在评论中更清楚地表明我正在使用功能性 setState(同样,不要让人混淆)。我需要澄清一点,我不需要帮助让这些特定的代码工作,它更多的是展示我希望能够做什么。在这方面,它伪代码即使你在反应中运行它实际上工作正常(除了参考丢失,正如预期的那样)。
EDIT2:正如vs1682在对这个问题的评论中指出的那样,在复制对象时使用对象扩展运算符会丢失引用。所以这个问题并没有真正具体反应(只是间接地)。
答案 0 :(得分:0)
也许这是一个令人震惊的错字,但你没有FooBar
。如果你不明白为什么需要它,也许你应该回到基础知识并阅读一下JavaScript ES6。
constructor
constructor(props) {
super(props)
this.state = {
active_object: null,
object1: { 'data': 'data1'},
}
}
不接受回调作为其主要参数......或者至少这不是约定。 this.setState
可以接受回调作为辅助参数,但这是为了处理this.setState
的异步性质。它没有明确地改变状态。
this.setState
此外,JavaScript惯例高度鼓励camelCase,而不是下划线。
编辑:我错了。可以在this.setState({ active_object: this.state.object1 })
中使用函数。事实上,这可能是个不错的主意。
答案 1 :(得分:0)
如果您在同一对象中引用属性(例如问题中的情况),则可以使用例如clone执行深层复制。那将&#34;重新链接&#34; (我不确定这里的术语)引用即使返回一个带有新内容的新对象。
我用这种方法看到的唯一缺点是,不会保留到达您正在克隆的对象的外的引用,而在浅层副本中(对象传播的内容)因为它根本不会修改参考文献,所以它会变成不可变形的帮助者。这个具体问题可能与clone有关。
无论如何,这是有效的,但我不知道性能的影响,或者考虑到反应和状态的功能性,它是不是很好的做法。
import React, { Component } from 'react';
import clone from 'clone';
class App extends Component {
constructor() {
super()
this.state = {
activeObject: null,
object1: { 'data': 'data1'},
}
}
modifyState() {
// point activeObject to object1
this.setState((state) => {
let newState = clone(state);
newState.activeObject = newState.object1;
return newState;
})
// modify it through the reference
this.setState((state) => {
let newState = clone(state);
newState.activeObject.data = 'data1-modified';
return newState;
})
}
render() {
return (
<div className="App">
<p onClick={ () => this.modifyState() }>modify</p>
{/* will show 'data1-modified' after modifyState */}
<p>{ this.state.object1.data }</p>
</div>
);
}
}
应该说带引用的克隆对象总是很棘手,并且需要更多的时间而不是你设置一个特殊的方法(特定于复制对象或数据结构)而不是依赖仅浅层/深层复制。在我的情况下,我认为&#34;正常&#34;浅拷贝和恢复引用的处理程序将是最好的方法。
或者,完全跳过引用,并依赖于唯一对象属性(例如和&#34; active&#34;标识符或&#34; id&#34;)来替换此方案中的麻烦参考。我怀疑在依赖于不可变状态的反应模型的值(和不变性)复制的语言中,由于缺少(不总是,但经常)对象/值引用,这不是一个问题。