使用 React.useMemo 将数组传递给 react-table,其中一个 useMemo 由于渲染而返回一个空数组

问题描述

我为我的数据使用了两个不同的 api,并使用 React memo 将它们作为变量传递给 react-table useTable 函数。当我在没有 useTable 的情况下运行我的所有代码时,reactMemo 似乎可以工作,我可以控制我传递给使用名为 headerColumns & colArrayData 的表的两个变量,但是当我使用 useTable 时,headerColumns 变量是一个空数组,破坏了 useTable。

我认为这一定是因为某些重新渲染或副作用导致反应导致数组在它到达 useTable 时为空。我该如何解决这个问题。

这是违规代码




const fetchWithId = (url,id) => fetch(`${url}?id=${id}`).then((r) => r.json());


const fetcher = (url) => fetch(url).then((r) => r.json());

export default function FormData() {

  const { data: cookieData,error: cookieError } = useSWR(
    "/api/cookie",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(() => {
    const inputData = inputNames?.findFormByID?.formInputVals?.data;
    let arr = [...inputData,{ name: "Sheet Add" }];
    console.log(arr);
    setInputDataState(arr);
  },[inputNames]);


  const header = inputDataState?.map((item,i) => {
    console.log(item);
    return { Header: item.name,accessor: `col${i}` };
  });
  console.log(header);

  const headerColumns = React.useMemo(() => header,[inputNames]); // THIS ONE DOES NOT SEEM TO WORK


  
  const well = data?.data.map((item,i) => {
    delete item.data["FormID"];
    delete item.data["user"];
    delete item.data["visible"];
    delete item.data["sheetName"];
    item.data["refId"] = item.ref["@ref"].id;
    const ok = Object.values(item.data);
    const ref = item.ref["@ref"].id;

    return ok.map((value,i) => {
      return { [`col${i}`]: value };
    });
  });

  const result = well?.map((a) => Object.assign({},...a));

  console.log(result);

  const colArrayData = React.useMemo(() => result,[data]); // THIS ONE SEEMS TO WORK

  console.log("data");


  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 <p>Loading</p>;

  return (
    <Layout>
      <h1>{inputNames?.findFormByID.name}</h1>
     
    </Layout>
  );
}

更新:我尝试将 useTable 移动到它自己的组件并将值作为道具传递并首先检查值是否存在。这样还是导致map is undefined错误,但是console.logs没有undefined

...
  {headerColumns && colArrayData && (
        <Table headerColumns={headerColumns} colArrayData={colArrayData} />
      )}
...

表组件

const Table = ({ headerColumns,colArrayData }) => {
  console.log(headerColumns);

  console.log(colArrayData);


  //THIS PART BREAKS THE CODE
  const tableInstance = useTable({ headerColumns,colArrayData });

  return (
    <div>
      <h1>Table</h1>
    </div>
  );
};

更新:这是我最近的一次尝试,但无济于事,并且没有未定义的控制台日志,所以不知道为什么 useTable 会出现这个问题



const Table = ({ data,inputDataState }) => {
  const header = inputDataState?.map((item,i) => {
    return { Header: item.name,accessor: `col${i}` };
  });

  const headerColumns = React.useMemo(() => header,[]);

  const well = data?.data?.map((item,i) => {
    delete item.data["FormID"];
    delete item.data["user"];
    delete item.data["visible"];
    delete item.data["sheetName"];
    item.data["refId"] = item.ref["@ref"].id;
    const ok = Object.values(item.data);
    const ref = item.ref["@ref"].id;

    //console.log(ok);

    return ok?.map((value,...a));

  const colArrayData = React.useMemo(() => result,[]);

  console.log(headerColumns);

  console.log(colArrayData);

  const tableInstance = useTable({ headerColumns,colArrayData });

  const {
    getTableProps,getTableBodyProps,headerGroups,rows,prepareRow,} = tableInstance;

  return (
    <table {...getTableProps()}>
      <thead>
        {
          // Loop over the header rows
          headerGroups.map((headerGroup) => (
            // Apply the header row props
            <tr {...headerGroup.getHeaderGroupProps()}>
              {
                // Loop over the headers in each row
                headerGroup.headers.map((column) => (
                  // Apply the header cell props
                  <th {...column.getHeaderProps()}>
                    {
                      // Render the header
                      column.render("Header")
                    }
                  </th>
                ))
              }
            </tr>
          ))
        }
      </thead>
      {/* Apply the table body props */}
      <tbody {...getTableBodyProps()}>
        {
          // Loop over the table rows
          rows.map((row) => {
            // Prepare the row for display
            prepareRow(row);
            return (
              // Apply the row props
              <tr {...row.getRowProps()}>
                {
                  // Loop over the rows cells
                  row.cells.map((cell) => {
                    // Apply the cell props
                    return (
                      <td {...cell.getCellProps()}>
                        {
                          // Render the cell contents
                          cell.render("Cell")
                        }
                      </td>
                    );
                  })
                }
              </tr>
            );
          })
        }
      </tbody>
    </table>
  );
};

const fetcher = (url) => fetch(url).then((r) => r.json());

export default function FormData() {
  const { data: cookieData,setInputDataState] = useState([]);

  useEffect(() => {
    const inputData = inputNames?.findFormByID?.formInputVals?.data;
    // let arr = [...inputData,{ name: "Sheet Add" }];
    // console.log(arr);
    setInputDataState(inputData);
  },[inputNames]);



  if (!data || loading) return <p>Loading</p>;

  return (
    <Layout>
      <h1>{inputNames?.findFormByID.name}</h1>

      {data && inputDataState && (
        <Table data={data} inputDataState={inputDataState} />
      )}
    </Layout>
  );
}

更新:最后我尝试在 React.useMemo 中移动地图函数,但仍然出现相同的错误。

const headerColumns = React.useMemo(() => {
    return inputDataState?.map((item,i) => {
      return { Header: item.name,accessor: `col${i}` };
    });
  },[]);

  const colArrayData = React.useMemo(() => {
    const well = data?.data?.map((item,i) => {
      delete item.data["FormID"];
      delete item.data["user"];
      delete item.data["visible"];
      delete item.data["sheetName"];
      item.data["refId"] = item.ref["@ref"].id;
      const ok = Object.values(item.data);
      const ref = item.ref["@ref"].id;

      //console.log(ok);

      return ok?.map((value,i) => {
        return { [`col${i}`]: value };
      });
    });

    return well?.map((a) => Object.assign({},...a));
  },colArrayData });
   // cannot read propery map of undefined

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)