title: setting state before a return always fails because it is not finished react
body: <p>I've found various questions similar to this but I could never get the solution to work, I'm not sure how to approach my problem. </p>
  
  <p>I have a fairly large grid (2D array) being generated in which I map it out and insert a <em>node</em> component. This process is done within a Grid component as it is generating this Grid.</p>
  
  <p>Breaking down my bug:</p>
  
  <p>I had it before when ComponentDidMount it would calculate the width and height of the array and create the grid, which worked in creating the grid, although, best practises tell me that you don't set state within ComponentDidMount unless its an HTTP call for data. </p>
  
  <p>Within the <code>render() { return () }</code> I had a if statement that checked if the state was undefined and render some sort of message such as <code>initalizing grid</code> and if the state of the array was not undefined it would render <code>DisplayGrid()</code>. Even after the grid was render, the if did not fire. </p>
  
  <p>The bottom line here is I have no idea how to properly delay my render before the state is loaded OR have my render reload once the state <em>is</em> set.</p>
  
  <p>I tried using a call back within <code>GenerateGrid()</code> to call <code>DisplayGrid()</code> and have my main component return call <code>GenerateGrid()</code> but the ended in an endless loop or after tweaking, once again, a undefined map once displaygrid was called.</p>
  
  <p>Here is a broken example of the full component:</p>
  
  <pre><code>export default class Grid extends React.Component {
    constructor(){
      super();
      this.state = {
        nodeSize : 50,
        nodeArray : [],
      }
    }
    // Generate a dynamic grid
    GenerateGrid = () =&gt; {
      const newNodeArray = [];
      const nodeSize = this.state.nodeSize;
  
      // get window inner hieght + width based on browser size (onstart) and remove 50px from height due to header
      let screenWidth = window.innerWidth;
      let screenHieght = window.innerHeight - 50;
  
      // get max amount of nodes based on node size
      const whNodes =  [Math.trunc(screenWidth / nodeSize),Math.trunc(screenHieght / nodeSize)];
  
      // begin creating the 2D array representing the grid
      for (let row = 0; row &lt; whNodes[0]; row++) { 
        const newRow = []; // initialize 1D array
        for (let col = 0; col &lt; whNodes[1]; col++) {
          newRow.push([]); // initalize 2D array
        }
        newNodeArray.push(newRow); // push into newNodeArray
      } 
      this.setState(
        {nodeArray : newNodeArray}, // set nodeArray state with the new 2D array based on viewport.
        // this.DisplayNodes()  // call function once completed if I used this GenerateGrid method within the return render (does not work)
      );
    }
    DisplayNodes = () =&gt; {
      const {nodeArray} = this.state.nodeArray; // get the node array from state
      console.log(nodeArray); // the bug is here. Always undefined.
      return (
        &lt;div id="grid"&gt;
          {nodeArray.map((row, rowIdx) =&gt; {
            return (
              &lt;div&gt;
                {row.map((node,nodeIdx) =&gt; &lt;Node/&gt;)}
              &lt;/div&gt;
            )
          })}
        &lt;/div&gt;
      )
    }
    render() {
      const {nodeArray} = this.state.nodeArray; // get the node array from state
      console.log(nodeArray);
      return (
        &lt;div id="grid-wrapper"&gt;
          {this.GenerateGrid()}
        &lt;/div&gt;
      )
    }
  }
  </code></pre>
  
  <p>Again I only ever got the grid to generate under componentDidMount but then I can never display it.</p>
  
  <p>Here is how I tried to handle this with the setState call back method:</p>
  
  <p>Within the GenerateGrid seState:</p>
  
  <pre><code>this.setState(
    {nodeArray : newNodeArray}, // set nodeArray state with the new 2D array based on viewport.
    this.DisplayNodes
  );
  </code></pre>
  
  <p>and then within the render of the main component:</p>
  
  <pre><code>  render() {
      return (
        &lt;div id="grid-wrapper"&gt;
          {this.GenerateGrid()} //create a infinte setState loop
        &lt;/div&gt;
      )
    }
  </code></pre>
  
  <p>This also spits out an error that map is undefined (aka the state isn't set before the <code>DisplayGrid</code> method is called.</p>