首页 > 解决方案 > 在 React 中的固定间隔后从数组中渲染项目

问题描述

我想一个接一个地排列项目。但它只显示数组的最后一个元素。

预期输出在 2 秒后显示“a”“b”,依此类推。

class Main extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      role: ["a","b","c"],
      display: "",
    }
  }
  componentDidMount() {
    for (let i of this.state.role) {
      setTimeout(() => {
        this.setState({ display: i})
      }, 2000)
    }
  }

  render() {
    return (
      <div>
          <h3>{this.state.display}</h3>
      </div>
    )
  }
}

ReactDOM.render(<Main />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id='root'></div>

标签: reactjs

解决方案


问题是您正在使用循环在 componentDidMount 上创建超时。在这种情况下,会发生什么情况是循环将立即完成创建 3 个计时器,这些计时器从开始和 setState 开始以几乎相同的 2 秒间隔解析,然后批处理所有三个状态更新调用,从而只显示最后一个。

为了解决这个问题,您可以使用setInterval如下

class Main extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      role: ["a","b","c"],
      display: "",
    }
  }
  componentDidMount() {
    var index = 0;
    this.timer = setInterval(() => {
      this.setState({ display: this.state.role[index]});
      index  = (index + 1)%(this.state.role.length);
    }, 2000)
  }

  componentWillUnmounnt() {
    clearInterval(this.timer);
  }
  render() {
    return (
      <React.Fragment>
          <h3>{this.state.display}</h3>
      </React.Fragment>
    )
  }
}

ReactDOM.render(<Main />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>


推荐阅读