如何每三秒钟渲染一次组件?

时间:2018-11-29 09:14:13

标签: javascript reactjs

import react, {Component} from 'react';

class Test extends component {
    constructor() {
        this.super();
        this.state = {
            message: [1, 2, 3, 4, 5]
        }
    }

    render() {
        return(
            <p>this.state.message</p>
        )
    }
}

如何每三秒钟一次将处于“消息”状态的项目呈现? 浏览器上所需的输出如下:

1 2 3 4 5

以上所有项目在三秒钟后出现。例如:显示1,然后显示“ ...”三秒钟以指示加载,然后显示2,然后显示“ ...”三秒钟,依此类推。非常感谢您的提前输入!

4 个答案:

答案 0 :(得分:3)

它与React文档中的this example非常相似。将当前消息的索引保存在state中,从0开始,然后在componentDidMount中使用setInterval调用setState来增加它的索引(如果需要,可以四处环绕或在到达终点时停止)。

也:

  • 更正您的extends子句:Component应该大写。
  • 您应该将constructor的参数传递给super
  • this.super()上不应包含this

类似这样的事情(这种情况一直存在,而不是停止):

const { Component } = React;

class Test extends Component {
    constructor(...args) {
        super(...args);
        this.state = {
            messages: [1, 2, 3, 4, 5],
            index: 0
        };
    }
    
    componentDidMount() {
      this.timer = setInterval(() => {
        this.setState(({messages, index}) => {
          index = (index + 1) % messages.length;
          return {
            index
          };
        });
      }, 3000); // 3000ms = three seconds
    }

    render() {
        const { index, messages } = this.state;
        return(
            <p>{messages[index]}</p>
        );
    }
}

ReactDOM.render(
  <Test />,
  document.getElementById("root")
);
<div id="root"></div>

<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>

回复:

constructor(...args) {
    super(...args);
    // ...
}

您会看到人们正在这样做,而不是很多,他们也在React文档中也这样做:

constructor(props) {
    super(props);
    // ...
}

那只会传递 first 参数。早些时候我就习惯了一直传递它们的习惯,但是我猜想React团队可能不会在标准构造函数调用中添加更多参数,因为遵循了仅在第一个传递的示例之后的代码量。

答案 1 :(得分:1)

这是另一种选择。

您需要引入一些新的状态才能在数字和...之间切换,例如isLoading

componentDidMount() {
   this.interval = setInterval(() => {
      this.setState(state => {
        if (state.message.length < 2) {
          clearInterval(this.interval);
          return null;
        }

        let newState = [...state.message];
        newState.shift();
        return {message: newState};
      });
   }, 3000);
}

render() {
  return(
    <p>{this.state.message[0]}</p>
  );
}

答案 2 :(得分:0)

您可以使用componentDidMount生命周期挂钩和setInterval来获得结果。

这里在工作codesandbox

P.S。正如t-j-crowder在他的回答中已经提到的,它与Reactjs文档中的示例非常相似。

答案 3 :(得分:0)

您可以尝试使用setTimeout控制从现在开始要运行的最短时间。

class Test extends React.Component {
    constructor(props) {
        super(props);

        this.timeout = 3000;
        this.availableMessages = [1, 2, 3, 4, 5];
        this.state = {
            itemsToShow: [],
            showLoader: false,
        };
    }

    processNextItem = () => {
      const item = this.getItemToShow();
      
      if (item) {
        this.setState({showLoader: true});

        setTimeout(() => {
          this.setState({showLoader: false});
          this.addItemToShow(item, this.processNextItem);
        }, this.timeout);
      }
    }

    getItemToShow = () => this.availableMessages.shift();

    addItemToShow = (item, onAdd) => {
      this.setState(({itemsToShow}) => ({
        itemsToShow: itemsToShow.concat(item)
      }), onAdd);
    }

    componentDidMount() {
      this.addItemToShow(this.getItemToShow());
      this.processNextItem();
    }

    render() {
        return (
           <div>
              {this.state.itemsToShow.map((item, index) => (
                <span key={index}>{item} </span>
              ))}
              {this.state.showLoader && '...'}
           </div>
        )
    }
}

ReactDOM.render(<Test />, 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>