React 服务器端状态同步
经过 有效的使用 useEffect 的学习,笔者逐渐意识到,useEffect
再 React 18 中已不适宜于服务器端进行状态同步。分享中,提到与服务器端状态同步主要可用的工具包括 Remix, Next.js, useSWR 以及 React-Query. 抛弃服务器端渲染技术不谈,笔者想着对于浏览器端的同步做进一步的学习。
useSWR
定义及使用
官方文档在此 useSWR,是 stale-while-revalidate
的缩写,即陈旧又重新生效。
使用 SWR,组件可以持续不断并自动获得数据流。UI 可以保持快速响应。
具体使用方法如下:
import useSWR from 'swr'
const fetcher = (...args) => fetch(...args).then(res => res.json())
function useUser (id) {
const { data, error } = useSWR(`/api/user/${id}`, fetcher)
return {
user: data,
isLoading: !error && !data,
isError: error
}
}
function Avatar ({ id }) {
const { user, isLoading, isError } = useUser(id)
if (isLoading) return <Spinner />
if (isError) return <Error />
return <img src={user.avatar} />
}
Optimistic UI
Optimistic UI is a pattern that you can use to simulate the results of a mutation and update the UI even before receiving a response from the server. Once the response is received from the server, the optimistic result is thrown away and replaced with the actual result.
预取数据
直接使用 ref="preload"
,
<link rel="preload" href="/api/data" as="fetch" crossorigin="anonymous">
将此代码放入 <head>
中,即可实现预取数据。所有使用 fetch
获取数据时,如果 url 完全一致,就会复用 prefetch 返回值。
更多细节
useSWR 当前刚发布了 2.0.0-rc.0。看当前的源代码。
import { useCallback, useRef, useDebugValue, useMemo } from 'react'
import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js'
可见目前 useSWR
已使用了 useSyncExternalStore。
React Query
定义及使用
传送门在此: React Query
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query'
const queryClient = new QueryClient()
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}
function Example() {
const { isLoading, error, data } = useQuery(['repoData'], () =>
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
res.json()
)
)
if (isLoading) return 'Loading...'
if (error) return 'An error has occurred: ' + error.message
return (
<div>
<h1>{data.name}</h1>
<p>{data.description}</p>
<strong>👀 {data.subscribers_count}</strong>{' '}
<strong>✨ {data.stargazers_count}</strong>{' '}
<strong>🍴 {data.forks_count}</strong>
</div>
)
}
观察 react-query 的源码,已使用了 useSyncExternalStore。
两者的源代码都值得进一步的学习。