J'essaie de comprendre comment déclencher setTimeout dans React.

Je suis assez nouveau dans React et jetais un coup d'œil à la documentation et au guide "tic-tac-toe". J'ai modifié le code du guide et je voulais réinitialiser l'état aux valeurs initiales après 3 secondes après avoir trouvé le gagnant du jeu.

La seule information que j'ai pu trouver était d'utiliser setTimeout dans le cycle de vie du composant, mais dans mon cas, je ne veux pas définir TimeTime si le composant a été monté. Je voudrais le déclencher après que calculateWinner() ait renvoyé une valeur véridique.

Est-il possible de réaliser quelque chose comme ça en réagissant ou pour ce faire, dois-je restructurer l'architecture de mes applications / composants?

Voici mon exemple: https://codesandbox.io/s/6l607x80r

La plupart des choses se passent dans le composant Board, où j'ai créé une fonction countDown(), mais je ne sais pas comment la déclencher.

0
Jan Cziżikow 15 avril 2018 à 11:29

3 réponses

Meilleure réponse

Vous pouvez utiliser le cycle de vie componentDidUpdate comme ceci:

componentDidUpdate() {
  if (calculateWinner(this.state.squares)) {
    this.countDown();
  }
}

Vous devrez également modifier votre fonction countDown:

setTimeout(() => {
  this.setState({
      squares: Array(9).fill(null),
      xIsNext: true,
    })
  }, 3000);
2
Doron Brikman 15 avril 2018 à 08:41

Tout d'abord, vous définissez le premier argument setTimeout doit être une fonction et donc vous écririez

countDown() {
    setTimeout(() => this.setState({
      squares: Array(9).fill(null),
      xIsNext: true,
    }), 3000);
  }

Deuxièmement, puisque vous calculez le gagnant dans la fonction de rendu, vous ajouteriez une autre variable d'état pour suivre le compte à rebours, puis déclencher le compte à rebours dans le rendu comme

const winner = calculateWinner(this.state.squares);
let status;
if(winner && !this.state.isCounting) {
  this.countDown();
}

Et le compte à rebours ressemblera

countDown() {
    this.setState({isCounting: true});
    setTimeout(() => this.setState({
      squares: Array(9).fill(null),
      xIsNext: true,
      isCounting: false
    }), 3000);
  }

Démo de travail

0
Shubham Khatri 15 avril 2018 à 08:40

Jusqu'à présent, j'ai trouvé deux façons de le faire.

Changer la fonction de compte à rebours pour se lier à (ceci), puis mettre un retour dans l'instruction if (winner) qui contient le html et le timer.

countDown() {
setTimeout(function() { this.setState({
  squares: Array(9).fill(null),
  xIsNext: true,
// old = }), 3000);
}); }.bind(this), 3000);  }

Et j'ai changé le si gagnant en ceci.

if (winner) {
  status = 'Winner: ' + winner;
  // Old code doesn't contain a return here.
  return (
    <div>
      <div className="status">{status}</div>
      <div className="board-row">
        {this.renderSquare(0)}
        {this.renderSquare(1)}
        {this.renderSquare(2)}
      </div>
      <div className="board-row">
        {this.renderSquare(3)}
        {this.renderSquare(4)}
        {this.renderSquare(5)}
      </div>
      <div style={{ marginBottom: 30 }} className="board-row">
        {this.renderSquare(6)}
        {this.renderSquare(7)}
        {this.renderSquare(8)}
      </div>
      <Button id="reset" onClick={this.reset}>Reset</Button>
  // Call counDown(this) after the button.
      {this.countDown(this)}
    </div>
  )
} else {
  status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
}

L'autre façon dont j'ai pu le faire fonctionner était d'ajouter setTimeout () dans if (gagnant)

if (winner) {
  status = "Winner: " + winner;
  // Just add setTimeout() and it will reset after 3 seconds.
  setTimeout(() => {
   this.setState({
      squares: Array(9).fill(null),
      xIsNext: true});
  }, 3000);
} else {
  status = "Next player: " + (this.state.xIsNext ? "X" : "O");
}

Voici un EXEMPLE

J'ai joué avec l'affichage d'un compte à rebours et je l'ajouterai si je le fais plus tard.

0
robscodebase 16 avril 2018 à 09:41