我有ClockBlock
组件,在其中将状态提升保存在对象“定时器”中:
class ClockBlock extends Component {
constructor(props){
super(props);
this.state = { timer: props.timer }; // timer from Redux store
}
render(){
return(
<div className="clockBlock">
<Circle timer={this.state.timer} updateTimer={this.updateTimer.bind(this)} />
<Clock timer={this.state.timer} updateTimer={this.updateTimer.bind(this)} />
<ClockTerms updateTimer={this.updateTimer.bind(this)} />
</div>
)
}
所有三个嵌套组件都通过updateTimer
函数相互影响。 (ClockTerms组件除外-它在一个方向上起作用)。函数在这里:
updateTimer(newDuration){
const newState = Object.assign( {}, this.state );
newState.timer.duration = newDuration;
this.setState( newState );
}
问题是-当我使用ClockTerms
组件更改计时器时,我也看到了Clock
组件中的更改(显然是通过道具)。同时,在Circle
函数的shouldComponentUpdate
组件中,我试图查看旧道具与新道具之间的区别。这是此功能:
shouldComponentUpdate(nextProps, nextState){
console.log( this.state.timer );
console.log( nextState.timer );
console.log( this.props.timer );
console.log( nextProps.timer );
return true;
}
所有console.log()调用都打印相同的数据-新道具。为什么?而且我该如何获得旧道具呢?
PS:我在上面简化了我的代码,从我的观点计算中删除了无关紧要的内容。如果重要的话,可以给出完整的代码。 我在这里也使用Redux,但在我看来,它参与度不高。 提前谢谢!
更新:在shouldComponentUpdate
(父)组件中放置相同的ClockBlock
函数时,我也会得到相同的图片;
答案 0 :(得分:1)
我通过将this.state与nextProps比较并更新状态解决了类似的情况。我认为这不是一个很好的解决方案,但没有提出其他建议。
state = {
dayOff: this.props.myProperty
}
shouldComponentUpdate(nextProps, nextState) {
const shouldUpdate = this.state.myProperty !== nextProps.myProperty;
if (shouldUpdate) this.state.myProperty = nextProps.myProperty
return shouldUpdate;
}
答案 1 :(得分:1)
您可以在功能上设置状态。因为setState
是异步的,所以当有多个调用setState
时,React使用传递给setState
的最新属性。
相反,您可以通过传递更新程序功能来更新状态。这将批处理所有状态更新。当Reacts生命周期开始更新状态时,它将按顺序处理所有待处理的更新程序功能。
这来自文档,描述了setState使用对象时发生的情况。
后续呼叫将覆盖同一呼叫中先前呼叫的值 周期,因此数量只会增加一次。如果下 状态取决于当前状态,我们建议使用更新程序 函数形式,而不是:
this.setState((state) => {
return {quantity: state.quantity + 1};
});
答案 2 :(得分:0)
问题在于updateTimer
在shouldComponentUpdate
运行之前触发。而已。因此,当您通过子组件更新父组件中的提升状态时(通过在props函数中传递),请记住shouldComponentUpdate
将获得已更改的状态和道具。