title: How to avoid setState() inside render() when state depends on render
body: <p>I have a grid that renders cards of variable heights.</p>
  
  <p>To get the height of the cards, I render the card wrapped in <code>ReactHeight</code> (<a href="https://github.com/nkbt/react-height" rel="noreferrer">https://github.com/nkbt/react-height</a>), which lets me pass a callback function to it when the height is ready.</p>
  
  <p>I keep the card heights in an array in the component <code>state</code>, which I update as card heights get reported.</p>
  
  <p>When all heights are available, I calculate the padding from the heights, which <code>render</code> passes to the cards </p>
  
  <p>In a simplified version, it looks like this.</p>
  
  <pre><code>class Grid extends Component {
    constructor() {
      ...
      this.state = { cardHeights: {}, paddings: [] }; //initial state
    }
  
    componentDidUpdate() {
      const i = setInterval(() =&gt; {
        if (all heights are ready) {
          // ...calculate paddings
          this.setState(paddings: calculatedPaddings);
  
          clearInterval(i);
        }
      }, 100);
      // *A*
    }
  
    updateCardHeights(index, height) {
      this.setState(prevState =&gt; ({
        cardHeights: {
          ...prevState.cardHeights,
          [index]: height,
        },
      }));
    }
  
    render() {
      // index = cards are indexed like 1   2  3
      //                                4   5  6
      //                                7   8  9
      //                                10 11 12
      //                                     ...
      return (
        &lt;ReactHeight onHeightReady={ height =&gt; this.updateCardHeights(index, height) }
           &lt;Card padding={this.state.paddings[index]}/&gt;
        &lt;/ReactHeight&gt;
      );
  
    }
  }
  </code></pre>
  
  <p>I know <code>setState()</code> calls <code>render</code>, and calling a function mutating the state inside <code>render</code> generally leads to an infinite loop.</p>
  
  <p>In my code, <code>render</code> calls a function that updates <code>this.state.cardHeights</code> array, and the rendering of its child component, <code>Card</code>, indirectly depends on <code>this.state.cardHeights</code>, since <code>this.state.paddings</code> that it directly depends on is calculated based on cardHeights on <code>componentDidUpdate()</code>.</p>
  
  <p>However, I cannot get the height of the <code>Card</code> component without rendering it, so the only way I can think of is making <code>padding</code> a <code>prop</code> to card and state of the component, and then changing the state after rendering.</p>
  
  <p>My question is:</p>
  
  <ol>
  <li><p>Somehow my code didn't result in an infinite loop even though I'm changing state inside render, but is a better way to do this?</p></li>
  <li><p><code>clearInterval()</code> inside my <code>componentDidUpdate()</code> function doesn't seem to work. I put a print statement in <code>*A*</code> part, and it keeps printing even when the if condition is met and <code>clearInterval()</code> is supposedly called. Can this be because of my bad state mutation?</p></li>
  </ol>