web-dev-qa-db-fra.com

Mettre à jour le composant React toutes les secondes

Je me suis amusé avec React et le composant de temps suivant ne fait que rendre Date.now() à l'écran:

import React, { Component } from 'react';

class TimeComponent extends Component {
  constructor(props){
    super(props);
    this.state = { time: Date.now() };
  }
  render(){
    return(
      <div> { this.state.time } </div>
    );
  }
  componentDidMount() {
    console.log("TimeComponent Mounted...")
  }
}

export default TimeComponent;

Quel serait le meilleur moyen de mettre à jour ce composant toutes les secondes pour redéfinir l'heure de la perspective React?

60
snowflakekiller

Vous devez utiliser setInterval pour déclencher la modification, mais vous devez également effacer le minuteur lorsque le composant se démonte pour éviter qu'il ne laisse des erreurs et une fuite de mémoire:

componentDidMount() {
  this.interval = setInterval(() => this.setState({ time: Date.now() }), 1000);
}
componentWillUnmount() {
  clearInterval(this.interval);
}
64
Waiski

Voici un exemple du site React.js: 

  class Timer extends React.Component {
          constructor(props) {
            super(props);
            this.state = { seconds: 0 };
          }

          tick() {
            this.setState(prevState => ({
              seconds: prevState.seconds + 1
            }));
          }

          componentDidMount() {
            this.interval = setInterval(() => this.tick(), 1000);
          }

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

          render() {
            return (
              <div>
                Seconds: {this.state.seconds}
              </div>
            );
          }
        }

 ReactDOM.render(<Timer />, mountNode);
68
Alireza Valizade

Dans la méthode componentDidMount lifecycle du composant, vous pouvez définir un intervalle pour appeler une fonction qui met à jour l'état.

 componentDidMount() {
      setInterval(() => this.setState({ time: Date.now()}), 1000)
 }
5
erik-sn
class ShowDateTime extends React.Component {
   constructor() {
      super();
      this.state = {
        curTime : null
      }
    }
    componentDidMount() {
      setInterval( () => {
        this.setState({
          curTime : new Date().toLocaleString()
        })
      },1000)
    }
   render() {
        return(
          <div>
            <h2>{this.state.curTime}</h2>
          </div>
        );
      }
    }
2
Jagadeesh

Donc, vous étiez sur la bonne voie. Dans votre componentDidMount(), vous auriez pu terminer le travail en implémentant setInterval() pour déclencher la modification, mais souvenez-vous que la façon de mettre à jour un composant est via setState(). Ainsi, dans votre componentDidMount(), vous auriez pu:

componentDidMount() {
  setInterval(() => {
   this.setState({time: Date.now()})    
  }, 1000)
}

De plus, vous utilisez Date.now() qui fonctionne, avec l’implémentation componentDidMount() que j’ai proposée ci-dessus, mais vous obtiendrez une longue série de mises à jour de chiffres désagréables qui ne sont pas lisibles par un humain, mais c’est techniquement le temps de mettre à jour chaque seconde en millisecondes depuis le 1er janvier 1970, mais nous voulons que ce temps soit lisible à la façon dont nous, les humains, lisons le temps. Ainsi, en plus d'apprendre et d'implémenter setInterval, vous voulez en savoir plus sur new Date() et toLocaleTimeString() et le mettre en œuvre de la manière suivante:

class TimeComponent extends Component {
  state = { time: new Date().toLocaleTimeString() };
}

componentDidMount() {
  setInterval(() => {
   this.setState({ time: new Date().toLocaleTimeString() })    
  }, 1000)
}

Remarquez que j'ai aussi supprimé la fonction constructor(), vous n'en avez pas nécessairement besoin, mon refactor équivaut à 100% à l'initialisation du site avec la fonction constructor().

0
Daniel