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

IT技术 javascript reactjs
2021-04-28 14:14:40

我有一个函数可以设置两次状态,但是 - 第二次setState必须在第一次发生后 500 毫秒后setState发生(动画目的)。

代码如下:

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

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

但是- 如果我这样做,React 会以某种方式将这两个合并setState为一个,并且我的动画无法按预期工作。

但是,如果我使用 hack:

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

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

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

4个回答

setStateReact 中的异步一样,您可能不会立即获得更新状态,但setStateprevStatesetState函数中为您提供参数以获取上次更新状态,因此您不会合并状态

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

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

只需使用更新您的值更新状态 prevState

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

如果你尝试这样的事情:

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

如果您希望在没有 setTimeout 的情况下计时,我会亲自在 JS 中使用动画。然而,这可能归结为“setState”在react中是异步的。

类似: 为什么 reactjs 中的 setState 是 Async 而不是 Sync?

然而,react 确实在 setState 中公开了一个回调——这对我有用

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

为了渲染性能,react批处理调用,setState这样顺序调用将一起执行,并且通常会反映在同一个渲染周期中。根据文档

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

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

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