title: Using React.useMemo to pass arrays to react-table, one of the useMemo's returns an empty array due to renders
body: <p>I am hitting two different api's for my data and am using React memo to pass them as variables into a react-table useTable function. When I run all my code without the useTable, the reactMemo seems to work, I can console the two variables that I am passing to use table called <code>headerColumns &amp; colArrayData</code> but when I use useTable the headerColumns variable is an empty array breaking useTable.</p>
  <p>I assume this must be because of some rerender or side effectr with react causing the array to be empty by the time it get's to useTable. How might I approach solving this.</p>
  <p>Here is the offending code</p>
  <pre><code>
  
  
  const fetchWithId = (url, id) =&gt; fetch(`${url}?id=${id}`).then((r) =&gt; r.json());
  
  
  const fetcher = (url) =&gt; fetch(url).then((r) =&gt; r.json());
  
  export default function FormData() {
  
    const { data: cookieData, error: cookieError } = useSWR(
      &quot;/api/cookie&quot;,
      fetcher
    );
    const Router = useRouter();
    const { data, error } = useSWR([`/api/data`, Router.query.id], fetchWithId);
  
    var test = `Bearer ${cookieData}`;
  
    const { loading, error: inputError, data: inputNames } = useQuery(
      INPUT_VALUES,
      {
        variables: { id: Router.query.id },
        context: {
          headers: {
            authorization: test,
          },
        },
        skip: !test,
      }
    );
  
    const [inputDataState, setInputDataState] = useState([]);
  
    useEffect(() =&gt; {
      const inputData = inputNames?.findFormByID?.formInputVals?.data;
      let arr = [...inputData, { name: &quot;Sheet Add&quot; }];
      console.log(arr);
      setInputDataState(arr);
    }, [inputNames]);
  
  
    const header = inputDataState?.map((item, i) =&gt; {
      console.log(item);
      return { Header: item.name, accessor: `col${i}` };
    });
    console.log(header);
  
    const headerColumns = React.useMemo(() =&gt; header, [inputNames]); // THIS ONE DOES NOT SEEM TO WORK
  
  
    
    const well = data?.data.map((item, i) =&gt; {
      delete item.data[&quot;FormID&quot;];
      delete item.data[&quot;user&quot;];
      delete item.data[&quot;visible&quot;];
      delete item.data[&quot;sheetName&quot;];
      item.data[&quot;refId&quot;] = item.ref[&quot;@ref&quot;].id;
      const ok = Object.values(item.data);
      const ref = item.ref[&quot;@ref&quot;].id;
  
      return ok.map((value, i) =&gt; {
        return { [`col${i}`]: value };
      });
    });
  
    const result = well?.map((a) =&gt; Object.assign({}, ...a));
  
    console.log(result);
  
    const colArrayData = React.useMemo(() =&gt; result, [data]); // THIS ONE SEEMS TO WORK
  
    console.log(&quot;data&quot;);
  
  
    console.log(headerColumns); // RETURNS AN EMPTY ARRAY WHEN useTable is set
  
    console.log(colArrayData);
  
    const tableInstance = useTable({ headerColumns, colArrayData }); //CAUSES CANNOT READ PROPERTY OF UNDEFINED
  
  
  
    if (!data || loading) return &lt;p&gt;Loading&lt;/p&gt;;
  
    return (
      &lt;Layout&gt;
        &lt;h1&gt;{inputNames?.findFormByID.name}&lt;/h1&gt;
       
      &lt;/Layout&gt;
    );
  }
  </code></pre>
  <p>UPDATE: I have tried moving the useTable to it's own component and passing the values as props and checking to see if the values exist first. This still results in the map is undefined error, but there is no undefined console.logs</p>
  <pre><code>...
    {headerColumns &amp;&amp; colArrayData &amp;&amp; (
          &lt;Table headerColumns={headerColumns} colArrayData={colArrayData} /&gt;
        )}
  ...
  </code></pre>
  <p>Table componenent</p>
  <pre><code>const Table = ({ headerColumns, colArrayData }) =&gt; {
    console.log(headerColumns);
  
    console.log(colArrayData);
  
  
    //THIS PART BREAKS THE CODE
    const tableInstance = useTable({ headerColumns, colArrayData });
  
    return (
      &lt;div&gt;
        &lt;h1&gt;Table&lt;/h1&gt;
      &lt;/div&gt;
    );
  };
  </code></pre>
  <p>UPDATE: This is my latest attempt to no avail, and there are no undefined console logs so not sure why useTable is having this issue</p>
  <pre><code>
  
  const Table = ({ data, inputDataState }) =&gt; {
    const header = inputDataState?.map((item, i) =&gt; {
      return { Header: item.name, accessor: `col${i}` };
    });
  
    const headerColumns = React.useMemo(() =&gt; header, []);
  
    const well = data?.data?.map((item, i) =&gt; {
      delete item.data[&quot;FormID&quot;];
      delete item.data[&quot;user&quot;];
      delete item.data[&quot;visible&quot;];
      delete item.data[&quot;sheetName&quot;];
      item.data[&quot;refId&quot;] = item.ref[&quot;@ref&quot;].id;
      const ok = Object.values(item.data);
      const ref = item.ref[&quot;@ref&quot;].id;
  
      //console.log(ok);
  
      return ok?.map((value, i) =&gt; {
        return { [`col${i}`]: value };
      });
    });
  
    const result = well?.map((a) =&gt; Object.assign({}, ...a));
  
    const colArrayData = React.useMemo(() =&gt; result, []);
  
    console.log(headerColumns);
  
    console.log(colArrayData);
  
    const tableInstance = useTable({ headerColumns, colArrayData });
  
    const {
      getTableProps,
      getTableBodyProps,
      headerGroups,
      rows,
      prepareRow,
    } = tableInstance;
  
    return (
      &lt;table {...getTableProps()}&gt;
        &lt;thead&gt;
          {
            // Loop over the header rows
            headerGroups.map((headerGroup) =&gt; (
              // Apply the header row props
              &lt;tr {...headerGroup.getHeaderGroupProps()}&gt;
                {
                  // Loop over the headers in each row
                  headerGroup.headers.map((column) =&gt; (
                    // Apply the header cell props
                    &lt;th {...column.getHeaderProps()}&gt;
                      {
                        // Render the header
                        column.render(&quot;Header&quot;)
                      }
                    &lt;/th&gt;
                  ))
                }
              &lt;/tr&gt;
            ))
          }
        &lt;/thead&gt;
        {/* Apply the table body props */}
        &lt;tbody {...getTableBodyProps()}&gt;
          {
            // Loop over the table rows
            rows.map((row) =&gt; {
              // Prepare the row for display
              prepareRow(row);
              return (
                // Apply the row props
                &lt;tr {...row.getRowProps()}&gt;
                  {
                    // Loop over the rows cells
                    row.cells.map((cell) =&gt; {
                      // Apply the cell props
                      return (
                        &lt;td {...cell.getCellProps()}&gt;
                          {
                            // Render the cell contents
                            cell.render(&quot;Cell&quot;)
                          }
                        &lt;/td&gt;
                      );
                    })
                  }
                &lt;/tr&gt;
              );
            })
          }
        &lt;/tbody&gt;
      &lt;/table&gt;
    );
  };
  
  const fetcher = (url) =&gt; fetch(url).then((r) =&gt; r.json());
  
  export default function FormData() {
    const { data: cookieData, error: cookieError } = useSWR(
      &quot;/api/cookie&quot;,
      fetcher
    );
    const Router = useRouter();
    const { data, error } = useSWR([`/api/data`, Router.query.id], fetchWithId);
  
    var test = `Bearer ${cookieData}`;
  
    const { loading, error: inputError, data: inputNames } = useQuery(
      INPUT_VALUES,
      {
        variables: { id: Router.query.id },
        context: {
          headers: {
            authorization: test,
          },
        },
        skip: !test,
      }
    );
  
    const [inputDataState, setInputDataState] = useState([]);
  
    useEffect(() =&gt; {
      const inputData = inputNames?.findFormByID?.formInputVals?.data;
      // let arr = [...inputData, { name: &quot;Sheet Add&quot; }];
      // console.log(arr);
      setInputDataState(inputData);
    }, [inputNames]);
  
  
  
    if (!data || loading) return &lt;p&gt;Loading&lt;/p&gt;;
  
    return (
      &lt;Layout&gt;
        &lt;h1&gt;{inputNames?.findFormByID.name}&lt;/h1&gt;
  
        {data &amp;&amp; inputDataState &amp;&amp; (
          &lt;Table data={data} inputDataState={inputDataState} /&gt;
        )}
      &lt;/Layout&gt;
    );
  }
  </code></pre>
  <p>UPDATE: And Finally I have tried moving the map functions inside the React.useMemo, but still get the same error.</p>
  <pre><code>const headerColumns = React.useMemo(() =&gt; {
      return inputDataState?.map((item, i) =&gt; {
        return { Header: item.name, accessor: `col${i}` };
      });
    }, []);
  
    const colArrayData = React.useMemo(() =&gt; {
      const well = data?.data?.map((item, i) =&gt; {
        delete item.data[&quot;FormID&quot;];
        delete item.data[&quot;user&quot;];
        delete item.data[&quot;visible&quot;];
        delete item.data[&quot;sheetName&quot;];
        item.data[&quot;refId&quot;] = item.ref[&quot;@ref&quot;].id;
        const ok = Object.values(item.data);
        const ref = item.ref[&quot;@ref&quot;].id;
  
        //console.log(ok);
  
        return ok?.map((value, i) =&gt; {
          return { [`col${i}`]: value };
        });
      });
  
      return well?.map((a) =&gt; Object.assign({}, ...a));
    }, []);
  
    console.log(headerColumns);
  
    console.log(colArrayData);
  
    const tableInstance = useTable({ headerColumns, colArrayData });
     // cannot read propery map of undefined
  </code></pre>