【问题标题】:setTimeout() in componentDidMount() does not work [duplicate]componentDidMount() 中的 setTimeout() 不起作用[重复]
【发布时间】:2018-08-22 21:48:12
【问题描述】:

我试图在 componentDidMount() 钩子中每 5 秒更改一次组件的状态,如下所示

import React, { Component } from 'react';

export default class ToTest extends Component {

  constructor(props) {
    super(props);
    this.state = {
      test: false
    };
  }

  componentDidMount() {
    setTimeout(() => { this.setState({ test: !this.state.test }) }, 5000);
  }

  renderDiv() {
    if(this.state.test) {
      return (<div>test is true</div>)
    }
    else {
      return (<div>test is false</div>)
    }
  }
  render() {
    return (
      <div>{ this.renderDiv() }</div>
    );
  }
}

但它只执行一次。它从 false 变为 true 一次,然后什么也没有。 我错过了什么?

【问题讨论】:

  • 你需要使用setInterval而不是setTimeout,它会一次又一次地调用同一个函数。

标签: javascript reactjs settimeout


【解决方案1】:

componentDidMount() 只在组件挂载时执行一次,并且您只安排一次。您必须使用setInterval() 定期安排它。

此外,当您根据当前状态更新状态时,您应该在 setState() 中使用回调,该回调将先前的状态作为 react 可能会批量调用 setState()

别忘了取消componentWillUnmount()中的定时器:

import React, { Component } from 'react';

export default class ToTest extends Component {
    state = {
        test: false,
    };

    componentDidMount() {
        this.timer = setInterval(
            () => this.setState(prevState => ({ test: !prevState.test })),
            5000,
        );
    }

    componentWillUnmount() {
        clearInterval(this.timer);
    }

    // other methods ...
}

【讨论】:

  • 这行得通,但我面临的问题是它一次又一次地重新渲染,因为 setState 和 componentWillUnmount 从不调用
  • @Sanaullah 然后在渲染方法中调用setState 或在没有合适条件的情况下调用componentDidUpdate。可能每次渲染都会触发新的更新。 componentWillUnmount 仅在组件完全卸载时调用一次。每次重新渲染后都不会调用它。
  • 那么我该如何清除Interval
  • @Sanaullah 我不知道您要做什么,所以我无法回答。使用相关代码提出新问题并使用链接发表评论。
【解决方案2】:

好吧setTimeout只会执行一次,你要找的是setInterval

https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout

WindowOrWorkerGlobalScope mixin 的 setTimeout() 方法(以及 window.setTimeout 的后继)设置一个执行函数的计时器 或指定的一段代码计时器到期后。

比较

WindowOrWorkerGlobalScope mixin 的 setInterval() 方法 反复调用函数或执行代码sn-p,固定 每次通话之间的时间延迟。

【讨论】:

    【解决方案3】:

    正如 cmets 中所说,您必须使用setInterval。函数setTimeout 被调用一次。确保在卸载组件时清除 setInterval。 https://reactjs.org/docs/react-component.html#componentwillunmount

    代码。

    import React, { Component } from 'react';
    
    export default class ToTest extends Component {
    
      constructor(props) {
        super(props);
        this.state = {
          test: false
        };
      }
    
      componentDidMount() {
        this.timer = setInterval(() => { this.setState({ test: !this.state.test }) }, 5000);
      }
    
      componentWillUnmount() {
        clearInterval(this.timer)
      }
    
    
      renderDiv() {
        if(this.state.test) {
          return (<div>test is true</div>)
        }
        else {
          return (<div>test is false</div>)
        }
      }
      render() {
        return (
          <div>{ this.renderDiv() }</div>
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多