使用RTK-Query Redux获取数据时data可打印但map报错求助
问题原因
- RTK Query 的查询钩子返回的
data在首次渲染(请求未完成阶段)默认是undefined,只有当请求成功返回后才会被赋值为接口返回的数据。 - 你看到
console.log(data)能打印出正确值,是因为组件会触发至少两次渲染:第一次请求发起时data为undefined会打印一次,第二次请求成功后触发重渲染,data被赋值为接口返回值会再打印一次。你在控制台最终看到的是第二次渲染打印的有效值,如果给打印加个前缀console.log('渲染时data:', data),就能清晰看到两次打印的不同结果。而你在 JSX 里直接调用data.map时,第一次渲染就会执行到这段逻辑,此时data还是undefined,自然就抛出了读取map方法失败的错误。
解决方案
1. 优先做非空判断再渲染
你可以任选以下任意一种方式处理渲染逻辑:
- 加载状态兜底:用
isFetching判断请求中时渲染加载态,请求成功后再渲染列表
const CoinList = () => { const { data, isFetching } = useGetCoinsQuery(); if (isFetching) return <div>加载中...</div>; // 走到这里请求已经完成,data一定有值 return ( <div> {data.map(coin => <div key={coin.id}>{coin.name}</div>)} </div> ) }
- 可选链+默认值兜底:不需要单独处理加载态的场景可以直接这么写
const CoinList = () => { const { data = [] } = useGetCoinsQuery(); // 解构时直接给默认空数组 // 或者渲染时用可选链 return ( <div> {data?.map(coin => <div key={coin.id}>{coin.name}</div>) ?? []} </div> ) }
2. TypeScript类型定义是推荐做法,但不是解决本次报错的必要条件
添加类型定义可以帮你在开发阶段提前规避类型错误,避免把非数组类型的值赋值给data导致运行时报错。你可以给RTKQ的endpoint指定返回值类型:
// 先定义你接口返回的单条coin数据类型 interface Coin { id: string; name: string; // 其他字段按需补充 } export const coinApi = createApi({ reducerPath: 'coinApi', baseQuery: fetchBaseQuery({ baseUrl }), endpoints: (builder) => ({ // 泛型第一个参数是返回值类型,第二个是入参类型(这里没有入参就传void) getCoins: builder.query<Coin[], void>({ query: () => createRequest(`/watchlist`), }), }), });
加完类型后,useGetCoinsQuery返回的data会自动带上Coin[] | undefined的类型,TypeScript也会在你直接调用data.map的时候提前抛出编译错误,避免你把问题带到运行时。
内容的提问来源于stack exchange,提问作者deagleshot32
相关产品推荐
相关产品推荐

