Comment éviter setState() à l'intérieur de render() lors de l'état dépend de rendu

J'ai une grille qui rend les cartes de variable hauteurs.

Pour obtenir la hauteur de la carte, j'ai rendu la carte enveloppé dans ReactHeight (https://github.com/nkbt/react-height), ce qui me permet de passer d'une fonction de rappel lorsque la hauteur est prêt.

Je garde la carte des hauteurs dans un tableau dans le composant state, qui-je mettre à jour étant donné que la carte des hauteurs signalés.

Lorsque toutes les tailles sont disponibles, j'ai calculer la marge sur les hauteurs, qui render passe pour les cartes

Dans une version simplifiée, il ressemble à ceci.

class Grid extends Component {
  constructor() {
    ...
    this.state = { cardHeights: {}, paddings: [] }; //initial state
  }

  componentDidUpdate() {
    const i = setInterval(() => {
      if (all heights are ready) {
        //...calculate paddings
        this.setState(paddings: calculatedPaddings);

        clearInterval(i);
      }
    }, 100);
    //*A*
  }

  updateCardHeights(index, height) {
    this.setState(prevState => ({
      cardHeights: {
        ...prevState.cardHeights,
        [index]: height,
      },
    }));
  }

  render() {
    //index = cards are indexed like 1   2  3
    //                               4   5  6
    //                               7   8  9
    //                               10 11 12
    //                                    ...
    return (
      <ReactHeight onHeightReady={ height => this.updateCardHeights(index, height) }
         <Card padding={this.state.paddings[index]}/>
      </ReactHeight>
    );

  }
}

Je sais setState() appels render, et l'appel d'une fonction de la mutation de l'état à l'intérieur render conduit généralement à une boucle infinie.

Dans mon code, render appelle une fonction qui met à jour this.state.cardHeights tableau, et le rendu de son enfant composant, Card, indirectement dépend this.state.cardHeights, depuis this.state.paddings qu'il dépend directement de la est calculé sur la base cardHeights sur componentDidUpdate().

Cependant, je ne parviens pas à la hauteur de la Card composant sans rendre, de sorte que la seule façon que je peux penser à est de faire padding un prop à la carte et de l'état du composant, et la modification de l'état après le rendu.

Ma question est:

  1. En quelque sorte mon code ne se traduira pas par une boucle infinie, même si je vais changer d'état à l'intérieur de rendu, mais c'est une meilleure façon de le faire?

  2. clearInterval() à l'intérieur de mon componentDidUpdate() fonction ne semble pas fonctionner. J'ai mis une instruction print dans *A* partie, et il garde l'impression, même lorsque la si la condition est remplie et clearInterval() est censé être appelé. Cela peut-il être à cause de mon mauvais état de mutation?

InformationsquelleAutor Eric Na | 2017-05-18