swr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import useSWR from 'swr'
function fetcher(key){
return fetch(key).then(resp=>resp.json)
}
和key有关所以没法和trpc一起用。

function Profile() {
const { data, error, isLoading } = useSWR('/api/user', fetcher)
const { data, error, isLoading } = useSWR('/api/user', fetcher,{refreshInterval:1000})
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
useSWR hook 接受一个字符串 key 和一个函数 fetcher,key 是数据的唯一标识符(通常是 API URL),并传递给 fetcher。fetcher 可以是任何返回数据的异步函数
基于请求的状态,这个 hook 返回 2 个值:data 和 error
1
2
3
4
5
默认情况下,key 将作为参数传递给 fetcher。所以下面这 3 个表达式是等价的:

useSWR('/api/user', () => fetcher('/api/user'))
useSWR('/api/user', url => fetcher(url))
useSWR('/api/user', fetcher)

通过包装swr为函数,避免逻辑隔离后重复请求或context传递数据

image-20240918144246736

cookie的swr读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const fetcher = (url) => fetch(url, { credentials: 'include' }).then((res) => res.json());
//我们定义了一个 fetcher 函数,并设置 { credentials: 'include' },这确保了请求会携带相关的 Cookie。credentials 的选项有以下几种:

//omit: 不发送任何 Cookie(默认行为)。
//same-origin: 只在同源请求时发送 Cookie。
//include: 在所有请求中发送 Cookie(跨域请求时也会发送)。
const {
data: user,
isLoading: isUserLoading,
error: fetchUserError
} = useSWR('/api/user/get',fetcher); // 通过 Cookie 来获取用户数据

或者SWR 默认使用 fetch 作为请求器(fetcher)。在使用 fetch 进行请求时,浏览器会自动携带相关的 Cookie
const {
data: user,
isLoading: isUserLoading,
error: fetchUserError
} = useSWR('/api/user/get');
  • 在大多数情况下,浏览器会自动将与目标域相关的 Cookie 附加到每个请求中。因此,当你在浏览器环境下发送请求到 /api/user/get 时,如果目标域设置了 Cookie(比如 SessionID 或者 Token),这些 Cookie 会自动附加到请求头中。
  • 例如,如果用户已经登录了,并且登录状态由一个会话 Cookie 管理,浏览器会自动将该 Cookie 附加到 /api/user/get 请求中,服务器端可以读取 Cookie 并根据会话来返回相应的用户数据。

服务器端处理 Cookie

  • 当请求到达服务器时,服务器会从请求头中读取 Cookie,检查用户的身份和权限。例如,如果 Cookie 包含一个有效的会话 ID 或者 JWT(JSON Web Token),服务器将验证这些信息并返回相应的用户数据。

进行两个swr先后读取时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Profile() {
const {
data: user,
isLoading: isUserLoading,
error: fetchUserError
} = useSWR('/api/user/get'); // 通过 Cookie 来获取用户数据

const { data: avatarUrl, isLoading, error } = useSWR(
isUserLoading ? null : '/api/avatar/get/' + user.id
);

if (isUserLoading || isLoading) return <Loading />;
if (fetchUserError) return <Error message={fetchUserError.message} />;
if (error) return <Error message={error.message} />;

return <img src={avatarUrl} alt={user.name} />;
}

代码中使用了 isUserLoading ? null : '/api/avatar/get/' + user.id,这是一个关键改进。这里的逻辑是,当 isUserLoadingtrue 时(即用户数据仍在加载中),SWR 不会发送请求获取用户头像数据。

useSWR 的第一个参数为 null 时,表示不进行请求。这样避免了在用户数据还没加载完成时就发出获取头像的请求,这样的请求很可能会失败或者返回错误。

在用户数据加载完成后,才能确定 user.id 的值,这样就可以动态地拼接 URL 来获取用户头像数据。这种方式确保了获取头像的请求只有在有了有效的 user.id 后才会执行。

swr修改数据

image-20240918151143515

####swr的老文档已经写的挺好了,很详细

#trpc的重复请求

和swr结合

或者直接用useQuery(),useMutation()函数

1
2
3
4
5
6
7
 自动
const [intervalMs, setIntervalMs] = useState(1000);

// 使用 tRPC 的查询钩子,结合 React Query 的 refetchInterval 进行自动更新
const { data, isLoading, error } = trpc.user.getAll.useQuery(undefined, {
refetchInterval: intervalMs, // 每隔 intervalMs 毫秒自动更新一次数据
});
1
2
3
4
5
6
7
8
9
10
11
+手动
const mutation = trpc.user.create.useMutation({
onSuccess: () => {
// 当 mutation 成功时,手动触发用户数据的重新获取
queryClient.invalidateQueries(trpc.user.getAll.getQueryKey());
},
});
const handleCreateUser = () => {
mutation.mutate({ name: newUserName });
};

useMutationReact Query(或类似库如 tRPC 的 React 集成中)提供的一个强大的钩子,专门用于处理变化性操作,如发送 POST、PUT、PATCH、DELETE 请求等。这些操作通常会改变服务器上的数据,而不是像 GET 请求那样仅仅是读取数据。

useMutation 的作用

useMutation 钩子用于执行带有副作用的异步操作,例如:

  • 创建资源(如新建用户、添加评论等)。
  • 更新资源(如编辑用户信息)。
  • 删除资源(如删除条目)。

它允许你对这些操作进行管理,并提供了以下功能:

  • 追踪异步操作的状态(如loadingsuccesserror)。
  • 支持请求成功后或失败后的回调函数。
  • 允许你手动处理缓存数据的更新(例如通过 invalidateQueries 来刷新相关的数据)。

基本使用

在使用 useMutation 时,你需要定义一个执行异步操作的函数(例如通过 fetchaxios 发起 HTTP 请求)。然后,你可以使用 mutate 函数来调用该异步操作。