gpt4 book ai didi

javascript - 状态为 : change only once 的 ES6 类 ReactJS

转载 作者:行者123 更新时间:2023-11-30 09:46:36 27 4
gpt4 key购买 nike

我完全是 ReactJS 的新手,当我创建计数器应用程序时有一点奇怪的行为

https://jsfiddle.net/8f5tqr74/2/

class CounterViewModel {
constructor() {
this.value = 5;
}

tick() {
//cannot move logic of this method to sendTick complex logic will be here
this.value++;
}

}

var Counter = React.createClass({
getInitialState: function () {
return new CounterViewModel();
},

sendTick: function () {
console.log("Before:",this.state);

var stateObj = this.state;
stateObj.tick();
this.setState(stateObj);
console.log("After:",this.state);
},

render: function () {
return <div>
{this.state.value}
<button onClick={this.sendTick}>Increase</button>
</div>
}


});


ReactDOM.render(<Counter />, document.getElementById('container'));

我的问题是此代码仅在我单击按钮时才第一次起作用在开发者控制台中得到这个之后

//first click
Before: CounterViewModel {value: 5}
After: CounterViewModel {value: 6}
//second click
Before: Object {value: 6}

在第二次点击状态类被刷新到对象,但是我没有在这个对象中进行操作

我的问题是:

1) 为什么 React 在 setState 之后刷新对象类?

2) 为什么 React 在 getInitialState 之后不刷新类对象?

3) 如何将复杂的逻辑放入 React 的状态对象中?我知道我可以重新创建具有更高值(value)的对象,并且一切都会很好(见下面的代码)

class CounterViewModel {
constructor(value) {
this.value = value;
}
}

var Counter = React.createClass({
getInitialState: function () {
return new CounterViewModel(5);
},

sendTick: function () {
this.setState(new CounterViewModel(this.state.value+1))
},

render: function () {
return <div>
{this.state.value}
<button onClick={this.sendTick}>Increase</button>
</div>
}


});


ReactDOM.render(<Counter />, document.getElementById('container'));

最佳答案

React 期望 state 是一个普通的 JS 对象,这就是为什么它在你调用 setState() 之后变成一个对象的原因。

此外,setState 不会立即改变 this.state,这意味着当它在您的代码中打印时

After: CounterViewModel {value: 6}

state 并没有真正改变,如果你将那个 console.log() 移动到 setState 的回调函数,就像这个 jsfiddle ,你会注意到状态改变后,state 变成了一个普通的对象

Before: CounterViewModel {value: 5}
After: Object {value: 6}

那么你如何解决这个问题?

您已将普通对象用作状态,您必须将其视为不可变对象。

var Counter = React.createClass({
getInitialState: function () {
return {counter: new CounterViewModel()}
},

sendTick: function () {
var stateObj = Object.assign(new CounterViewModel(),this.state.counter); // Deep clone
stateObj.tick();
this.setState({counter: stateObj});
},

render: function () {
console.log(this.state);
return <div>
{this.state.counter.value}
<button onClick={this.sendTick}>Increase</button>
</div>
}


});

working jsfiddle

关于javascript - 状态为 : change only once 的 ES6 类 ReactJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38688902/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com