Phi*_*ong 5 javascript reactjs
我不知道这是一个已知的问题还是一个预期的功能,但我发现了一个有趣的问题.
所以我们都知道如果我们想在React中呈现一个反应值,我们必须将值放在状态并使用setState:
constructor() {
super();
this.state = { counter: 0 }
this.incrementButtonListener = (e) => {
e.preventDefault();
this.setState(prevState => ({ counter: prevState.counter + 1 }));
};
}
render() {
return (
<div>
<h1>{this.state.counter}</h1>
// When clicked, counter increments by 1 and re-renders
<button onChange={this.incrementButtonListener}>Increment</button>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
但是如果我们counter作为一个字段属性,render()将只捕获counter创建组件的快照,即使counter递增,结果也不会在render()中被反应显示:
constructor() {
super();
this.counter = 0;
this.incrementButtonListener = (e) => {
e.preventDefault();
this.counter++;
};
}
render() {
return (
<div>
<h1>{this.counter}</h1>
// When clicked, counter increments by 1 but the difference is NOT rendered
<button onChange={this.incrementButtonListener}>Increment</button>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
对?基本的东西.
然而,当我试图摆弄这段代码时,有一个有趣的发生.我们将反击作为一个场地财产,其他一切都完好无损.唯一的区别是,在incrementButtonListener,我要添加setState上someStateProperty:
constructor() {
super();
this.counter = 0;
this.incrementButtonListener = (e) => {
e.preventDefault();
this.counter++;
/*-------------------------------ADD THIS*/
this.setState({});
// You have to pass an object, even if it's empty. this.setState() won't work.
/*-----------------------------------------*/
};
}
render() {
return (
<div>
<h1>{this.counter}</h1>
// Surprise surprise, now this.counter will update as if it was in the state!
<button onChange={this.incrementButtonListener}>Increment</button>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
这一次,this.counter更新,好像它处于状态!
所以我的假设是,每次调用setState时(即使使用空对象作为参数),render()this.counter也会再次运行并重新计算,从而递增.当然,它不会像国家财产那样100%被动.但是,在这个用例中,唯一的时间this.counter会改变,就是当我点击Increment按钮时.所以,如果我在监听器中放置一个setState,它就好像this.counter处于状态一样.
现在,我不确定这是一个可接受的行为还是一个意外的黑客行为,以及我是否应该使用它.有人能帮我解释一下吗?
如果你想看到行动中的行为,这是一个小提琴.您可以注释this.setState({})第7行中的位以查看差异.
因为您没有拦截状态的更改,所以它会导致重新渲染,从而导致使用增量实例属性。这是设计使然。React 状态的任何更改都会导致组件重新渲染,除非您使用生命周期钩子来控制是否应该发生这种情况。
请参阅https://reactjs.org/docs/react-component.html#shouldcomponentupdate