在React中固定间隔后从数组渲染项目

时间:2019-03-18 06:10:27

标签: reactjs

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

预期的输出在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>

3 个答案:

答案 0 :(得分:4)

问题是您正在使用循环在componentDidMount上创建超时。在这种情况下,将发生循环,循环将立即创建3个计时器,这些计时器在距start和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"/>

答案 1 :(得分:0)

您可以使用多个index来创建3个不同的超时。

class Main extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      role: ["a","b","c"],
      display: "",
    }
  }
  componentDidMount() {
    this.state.role.forEach((item, index) => {
      setTimeout(() => {
        this.setState({ display: item})
      }, 2000*(index+1))
    })
  }

  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>

答案 2 :(得分:0)

问题是for (x of y)直接运行,并且所有三个setTimeouts几乎同时创建,因此您只能看到最后一个的结果,因为它们之间存在1-2 ms的差异。 我使用for (x in y)代替了项索引。然后,我使用项目索引根据其索引来计算其超时。 这是我的方法:


import React, { Component } from "react";

export default class Main extends Component {
  constructor(props) {    super(props);
    this.state = {
      role: ["a", "b", "c"],
      display: ""
    };
  }

  componentDidMount() {
    for (let i in this.state.role) {
      setTimeout(() => {
        this.setState({
          display: this.state.role[i],
        });
      }, 2000 * i);
    }
  }

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