我不知道这是一个已知的问题还是一个预期的功能,但我发现了一个有趣的问题.
所以我们都知道如果我们想在React中呈现一个反应值,我们必须将值放在状态并使用setState:
constructor() {
super();
this.state = { counter: 0 }
this.incrementButtonListener = (e) => {
e.preventDefault();
this.setState(prevState => ({ counter: prevState.counter + 1 }));
};
}
render() {
return (
但是如果我们将counter作为字段属性,render()将仅在创建组件时捕获计数器的快照,并且即使计数器递增,结果也不会在render()中被反应显示:
constructor() {
super();
this.counter = 0;
this.incrementButtonListener = (e) => {
e.preventDefault();
this.counter++;
};
}
render() {
return (
对?基本的东西.
然而,当我试图摆弄这段代码时,有一个有趣的发生.我们将反击作为一个场地财产,其他一切都完好无损.唯一的区别是,在incrementButtonListener中,我将在someStateProperty上添加一个setState:
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 (
这一次,this.counter更新,好像它处于状态!
所以我的假设是,每次调用setState时(即使使用空对象作为参数),render()也会再次运行,this.counter将重新计算,从而递增.当然,它不会像国家财产那样100%被动.但是,在这个用例中,this.counter改变的唯一时间是单击Increment按钮.所以,如果我在侦听器中放置一个setState,它就好像this.counter处于状态一样.
现在,我不确定这是一个可接受的行为还是一个意外的黑客行为,以及我是否应该使用它.有人能帮我解释一下吗?
如果您想查看行动中的行为,这是一个fiddle.您可以注释掉第7行中的this.setState({})位以查看差异.
最佳答案
因为您没有拦截状态更改,所以它会导致重新呈现,从而导致使用增量实例属性.这是设计的.对React状态的任何更改都将导致组件重新呈现,除非您使用生命周期钩子来控制是否应该发生.
见https://reactjs.org/docs/react-component.html#shouldcomponentupdate