react-table结合react-query报reading 'forEach'类型错误如何解决
问题原因
你遇到的报错是useTable接收到的data参数为undefined导致的,核心有两个错误点:
- react-query返回值解构错误
react-query的useQuery钩子返回的响应数据字段名为data,并不是你写的apiResponse,所以你解构出来的apiResponse永远是undefined。后续执行setData(apiResponse?.data)时,相当于把本地的data状态从初始的空数组覆盖为undefined。 - useTable执行时机早于加载判断
React hooks必须在组件顶层执行,所以你的useTable调用会早于if (isLoading || !data)的返回判断,只要data为undefined,useTable内部调用data.forEach就会直接抛出错误。
修复方案
步骤1:修正useQuery的解构
给useQuery返回的data字段重命名即可拿到接口响应对象:
// 把原来的解构改成这样,给返回的data重命名为apiResponse const { data: apiResponse, isLoading } = useQuery('users', () => axios.get(`http://www.test.devel/users`));
步骤2:保证传给useTable的data永远为数组
有两种可选方案,选一种即可:
- 方案A:给data加兜底默认值,不需要修改原有逻辑结构
// 要么更新state的时候兜底 React.useEffect(() => { setData(apiResponse?.data ?? []); }, [apiResponse]); // 要么传给useTable的时候兜底 const tableInstance = useTable( { columns, data: data ?? [], defaultColumn, updateMyData }, useBlockLayout, useResizeColumns );
- 方案B(更推荐):把表格逻辑拆分到子组件,加载完成后再渲染,避免无意义的hooks执行
// CLGrid组件里修改返回逻辑 if (isLoading || !apiResponse?.data) { return <div>Loading...</div>; } // 加载完成后再渲染真正的表格组件,把data和columns传进去 return <TableInner columns={columns} data={apiResponse.data} /> // 单独拆分TableInner组件放原来的表格逻辑 function TableInner({columns, data}) { // 这里面写原来的updateMyData、defaultColumn、useTable等逻辑 }
额外优化建议
你不需要把useQuery返回的数据再存一份到本地state,直接用useQuery返回的数据即可,既少维护一份状态,也能避免数据不同步的问题。
内容的提问来源于stack exchange,提问作者Primordial_Hamster
相关产品推荐
相关产品推荐

