在单个函数中设置状态两次 - ReactJS

时间:2018-06-06 16:05:12

标签: javascript reactjs

我有一个设置状态两次的函数,但是第二个setState必须在自第一个setState出现以来500ms后发生(动画目的)。

代码如下:

const showAnimation = () => {
   this.setState({ hidden: false });

   setTimeout(() => {
      this.setState({ hidden: true });
   }, 500);
};

然而 - 如果我这样做,React会以某种方式将这两个setState合并为一个,我的动画无法正常工作。

但是,如果我使用黑客攻击:

const showAnimation = () => {
   setTimeout(() => {
      this.setState({ hidden: false });
   }, 0);  // ------------------------------> timeout 0

   setTimeout(() => {
      this.setState({ hidden: true });
   }, 500);
};

它按预期工作。但是,我仍然不喜欢它,我担心它可能是某种黑客攻击。对于这种情况有没有更好的解决方案?谢谢:))

4 个答案:

答案 0 :(得分:1)

如果你尝试这样的话:

const showAnimation = () => {
    this.setState({ hidden: false }, () => {
      setTimeout(() => {
        this.setState({ hidden: true });
      }, 500);
    }
  }

答案 1 :(得分:1)

如果你想在没有setTimeout的情况下计时,我会亲自在JS中使用动画。然而,这可能是因为'setState'在反应中是异步的。

类似的: Why is setState in reactjs Async instead of Sync?

然而,react确实会在setState中暴露回调 - 这对我有用

this.setState(
            { hidden : false },
            () => {
                setTimeout(()=>{this.setState({hidden : true})}, 500)
            }
        );

答案 2 :(得分:0)

对于渲染性能,将批量调用反应到setState,以便顺序调用将一起执行,并且通常会反映在同一渲染周期中。根据{{​​3}}:

  

setState()并不总是立即更新组件。它可以批量推迟更新或推迟更新。这使得在调用setState()之后立即读取this.state是一个潜在的陷阱。

为了确保在第二次调用之前执行了第一个setState,您可以将setState一个回调作为第二个参数传递。它并不完美,但类似以下内容将确保您对setState的第二次调用只会发生一次hidden: false

const showAnimation = () => {
this.setState({ hidden: false }, () => setTimeout(() => {
   this.setState({ hidden: true });
  }, 500););
};

答案 3 :(得分:0)

由于setState在React中是异步的,你可能不会立即获得更新状态,但是setState为setState函数提供了prevState参数以获得最后更新状态,因此你不会合并状态

语法在你的情况下是这样的

this.setState((prevState) => { hidden: false }, () => {
      setTimeout(() => {
        this.setState({ hidden: !prevState.hidden });
      }, 500);
    }
});

使用prevState

将您的值更新为更新状态

如果我理解你的问题是正确的,这应该可以正常工作 如果需要更多说明,请告诉我