useQuery获取数据后useEffect未触发的问题排查
问题分析与解决方案
从你的日志和代码来看,useQuery已经成功获取到数据,但依赖data的useEffect未触发,无法将数据存入context。下面是具体的原因排查和解决办法:
可能的原因及对应方案
1. React浅比较未识别到data变化
useEffect的依赖数组采用浅比较判断是否触发回调。如果Apollo Client返回的data对象引用未发生变化(比如缓存更新时复用了原对象),React会认为依赖没有更新,跳过useEffect执行。
解决办法:
- 使用数据中的唯一标识作为依赖(比如
data?.game?.id),确保数据更新时依赖值必然变化:useEffect(() => { if (data) { setLobbyData(data); console.log('%%%%%%%%Data', data); } }, [data?.game?.id]); - 或者自定义深比较的
useEffect,替代默认的浅比较:import { useEffect, useRef } from 'react'; import _ from 'lodash'; // 需引入lodash或自行实现深比较 function useDeepCompareEffect(callback: () => void, dependencies: any[]) { const ref = useRef<any[]>([]); if (!_.isEqual(dependencies, ref.current)) { ref.current = [...dependencies]; } useEffect(callback, [ref.current]); } // 使用示例 useDeepCompareEffect(() => { setLobbyData(data); console.log('%%%%%%%%Data', data); }, [data]);
2. 改用useQuery的onCompleted回调更可靠
相比依赖useEffect监听data变化,直接在useQuery的onCompleted回调中处理数据存入context的逻辑,更贴合GraphQL查询的生命周期,避免React渲染机制带来的不确定性。
解决办法:
修改useQuery配置,添加onCompleted回调:
const lobbyDataQuery = useQuery<GetGame, GetGameVariables>(GET_LOBBY_DATA, { variables: { gameId: params.id }, notifyOnNetworkStatusChange: true, pollInterval: 5000, // 首次查询、轮询更新完成时都会触发 onCompleted: (newData) => { setLobbyData(newData); console.log('%%%%%%%%Data', newData); }, });
3. 确保解构与依赖的一致性
检查解构的data是否和lobbyDataQuery.data保持同步,避免因变量作用域问题导致依赖失效。可以直接使用lobbyDataQuery.data作为useEffect的依赖:
useEffect(() => { const currentData = lobbyDataQuery.data; setLobbyData(currentData); console.log('%%%%%%%%Data', currentData); }, [lobbyDataQuery.data]);
4. 移除冗余的轮询启动代码
你在第二个useEffect中调用了lobbyDataQuery.startPolling(5000),但useQuery配置里已经设置了pollInterval: 5000,重复启动轮询可能引发数据更新异常,建议移除冗余代码:
useEffect(() => { console.log('{{{{{{{', isFocused, lobbyDataQuery.error); if (isFocused) { refetch(); // 已在useQuery配置中设置pollInterval,无需重复调用startPolling console.log('XXXXXXXXXXXXsetLobbyData', lobbyDataQuery.data); setLobbyData(lobbyDataQuery.data); } }, [isFocused, refetch, lobbyDataQuery.data]);
内容的提问来源于stack exchange,提问作者user3675843
相关产品推荐
相关产品推荐

