前端技术

React 服务器端状态同步

2022-10-30  本文已影响0人  吴摩西

经过 有效的使用 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

两者的源代码都值得进一步的学习。

上一篇下一篇

猜你喜欢

热点阅读