React Query调用setQueryData后组件未重新渲染问题排查
React Query 缓存更新后组件不刷新问题
我是React Query新手,想要实现以下流程:执行mutation→缓存响应数据→通过指定key访问数据。
访问数据的组件代码
function Test() { const client = useQueryClient() const bla = client.getQueryData(['auth']) console.log('blaa', bla) return ( <div> <TestInsideTest /> </div> ) }
执行mutation的组件代码
function TestInsideTest() { const loginMutation = useLoginMutation() return ( <div> I am the test inside test press the button <br /> <button onClick={() => loginMutation.mutate()}>Do fetch</button> </div> ) }
mutation代码
export const useLoginMutation = () => { const queryClient = useQueryClient() return useMutation({ mutationFn: () => Promise.resolve({ access_token: '123' }), onSuccess: (data: { access_token: string }) => { queryClient.setQueryData(['auth'], data) }, }) }
点击按钮后,控制台没有任何更新,但热重载后能正确获取数据。请问我哪里遗漏了?
问题原因
你直接用client.getQueryData(['auth'])读取缓存值,这个方法只是同步获取当前缓存快照,不会让组件订阅缓存的变化。当mutation通过setQueryData更新缓存后,Test组件没有感知到数据变化,自然不会重新渲染,控制台也就不会输出新值;热重载时组件重新初始化,才会读取到更新后的缓存数据。
解决方案
要用useQuery来订阅指定key的缓存数据,它会自动监听缓存变化并触发组件重渲染。因为我们不需要主动发起查询,只需要订阅缓存,所以可以把enabled设为false:
修改后的Test组件代码:
function Test() { const { data: bla } = useQuery({ queryKey: ['auth'], queryFn: () => null, // 无需发起实际请求,仅订阅缓存 enabled: false, // 禁用自动查询 }) console.log('blaa', bla) return ( <div> <TestInsideTest /> </div> ) }
这样当mutation更新['auth']的缓存后,Test组件会立即感知到变化并重新渲染,控制台就能输出最新的缓存值了。
内容的提问来源于stack exchange,提问作者Nick Gr
相关产品推荐
相关产品推荐

