React Query 是一个强大的库,用于在 React 应用程序中处理 server state,它提供了数据获取、缓存、同步和更新等功能。要从一个同级组件中重取数据,我们可以利用 React Query 提供的 useQueryClient
钩子。以下是一个详细步骤以及示例代码:
步骤
-
确保 React Query 已经在项目中设置好。 确保你的应用已经用
QueryClientProvider
包装,并且传入了一个QueryClient
实例。 -
在源组件中使用
useQuery
钩子。 这里的 "源组件" 指的是执行数据获取的组件。 -
在目标组件中使用
useQueryClient
钩子来获取queryClient
。 这个钩子允许你访问 queryClient 实例,通过这个实例我们可以访问 React Query 的缓存系统和工具。 -
在目标组件中调用
queryClient.invalidateQueries
方法。 使用此方法可以使一个或多个查询失效,这将触发重新取数据。你可以指定特定的查询 key 来仅使那些查询失效。
示例代码
假设我们有两个组件,ComponentA
和 ComponentB
。ComponentA
负责获取用户数据,而 ComponentB
可以触发重新获取这些数据。
jsx// App.js import React from 'react'; import { QueryClient, QueryClientProvider } from 'react-query'; import ComponentA from './ComponentA'; import ComponentB from './ComponentB'; const queryClient = new QueryClient(); function App() { return ( <QueryClientProvider client={queryClient}> <ComponentA /> <ComponentB /> </QueryClientProvider> ); } export default App;
jsx// ComponentA.js import React from 'react'; import { useQuery } from 'react-query'; async function fetchUserData() { const response = await fetch('https://api.example.com/users'); if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); } function ComponentA() { const { data, error, isLoading } = useQuery('users', fetchUserData); if (isLoading) return <div>Loading...</div>; if (error) return <div>Error: {error.message}</div>; return ( <div> {data.map(user => ( <p key={user.id}>{user.name}</p> ))} </div> ); } export default ComponentA;
jsx// ComponentB.js import React from 'react'; import { useQueryClient } from 'react-query'; function ComponentB() { const queryClient = useQueryClient(); const refetchUsers = () => { queryClient.invalidateQueries('users'); }; return ( <button onClick={refetchUsers}>Refetch Users</button> ); } export default ComponentB;
总结
在这个例子中,ComponentA
使用 useQuery
来获取用户数据。ComponentB
有一个按钮,当用户点击按钮时,通过调用 queryClient.invalidateQueries('users')
,触发 ComponentA
重新获取最新的用户数据。这种方法的好处是组件之间的解耦,它们通过查询键(在本例中是 'users'
)而不是直接引用或状态提升来相互影响。这使得代码更容易维护和扩展。