javascript – setState意外更新非状态属性

前端之家收集整理的这篇文章主要介绍了javascript – setState意外更新非状态属性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我不知道这是一个已知的问题还是一个预期的功能,但我发现了一个有趣的问题.

所以我们都知道如果我们想在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

猜你在找的JavaScript相关文章