我在 next.js 應用程式上使用 react-query 實作了資料擷取和更新的基本實作。 我的目標是在突變後更新數據。 目前,資料僅在選項卡刷新時更新。但如果沒有用戶交互,它就不會改變。
我發現選項卡刷新時發生資料更新是由於 refetchOnWindowFocus
預設行為。
但是伺服器端更新資料後如何失效呢? 這是相關的程式碼片段。
注意:我正在使用 Hydration 來使用 react-query SSR 功能。文件
_app.jsx
const [queryClient] = React.useState(() => new QueryClient()); return ( <QueryClientProvider client={queryClient}> <Hydrate state={pageProps.dehydratedState}> <Component {...pageProps} /> </Hydrate> </QueryClientProvider>
首頁.jsx
const {data} = useQuery({ queryKey: [queryKeys.key], queryFn: fetchData, staleTime: 1000 * 10, // this doesn't affect on anything //refetchInterval: 2000, this updates every 2 seconds }); return ( <div> <Article articles={data} /> </div> ); export const getServerSideProps = async () => { const queryClient = new QueryClient(); await queryClient.prefetchQuery([queryKeys.key], fetchData); return { props: { dehydratedState: dehydrate(queryClient) } }; };
文章.jsx
const Article = ({articles}) => { const [title, setTitle] = useState(""); const queryClient = new QueryClient(); const { mutate } = useMutation({ mutationFn: async (article) => { return await axios.post(url, article); }, onSuccess: (data) => { console.log("data", data) // data is displayed, onSuccess is called queryClient.invalidateQueries({ queryKey: [queryKeys.key] }); }, }); const changeTitleHandleClick = () => { mutate({ id: new Date(), title: title }); setTitle(""); }; ....
任何幫助將不勝感激
更新:refetchInterval:2000
每2秒更新一次,但這會每2秒觸發網路請求,所以我不確定這是重新驗證的最佳實踐。
更新:onSuccess
方法內的控制台在突變時顯示,這表示邏輯有問題,因為即使金鑰不同,這也應該有效:queryClient .invalidateQueries()
其中我沒有指定任何鍵而是觸發所有查詢。
但即使這樣也不會更新。為什麼?
您實現突變的方式,它應該在成功突變後重新取得查詢:
如果這不起作用,則表示您的突變不成功。檢查
onSuccess
回呼是否被呼叫。如果呼叫
onSuccess
回調,但未重新提取您的查詢,則可能表示queryKey
不符。出於測試目的,請嘗試將過濾器擴大到:應該重新取得所有查詢。如果有效,您就知道您的
queryKey
過濾器不符。仔細看看,你正在失效:
但是在您的自訂掛鉤中,您正在使用:
所以看起來它們確實不同,因此不匹配。另外,請務必使用
@tanstack/react-query-devtools
來更了解快取中的查詢和鍵。問題是在元件
Article.jsx
中,我在每個渲染中建立一個新的 QueryClient,因此它獲得了一個新的緩存,因此沒有更新。相反,我必須使用
useQueryClient
掛鉤,它會傳回目前實例。const queryClient = useQueryClient();