Mutation
Revalidate(重新验证)
你可以通过调用 mutate(key)
全局的向所有具有相同 key 的 SWR 广播重新验证消息。
该示例显示了当用户点击“注销”按钮时如何自动重新请求登录信息(例如:在 <Profile/>
内)。
import useSWR, { mutate } from 'swr'function App () { return ( <div> <Profile /> <button onClick={() => { // 将 cookie 设置为过期 document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;' // 告诉所有具有该 key 的 SWR 重新验证 mutate('/api/user') }}> Logout </button> </div> )}
Mutation and POST Request
在很多情况中,对数据应用本地 mutation 是一种让更改感觉更快的好办法 - 无需等待远程数据源。
使用 mutate
,你可以以编程方式更新本地数据,同时重新验证并最终将其替换为最新数据。
import useSWR, { mutate } from 'swr'function Profile () { const { data } = useSWR('/api/user', fetcher) return ( <div> <h1>My name is {data.name}.</h1> <button onClick={async () => { const newName = data.name.toUpperCase() // 立即更新本地数据,但禁用重新验证 mutate('/api/user', { ...data, name: newName }, false) // 向 API 发送请求更新源 await requestUpdateUsername(newName) // 触发重新验证(重新请求)以确保本地数据是正确的 mutate('/api/user') }}>Uppercase my name!</button> </div> )}
点击上面示例中的按钮将在本地更新客户端数据,并发送一个 POST 请求来修改远程数据,尝试请求最新数据(重新验证)。
但是很多 POST API 只会直接返回更新后的数据,所以我们不需要再次重新验证。下面这个示例展示了 “本地更改 - 请求 - 更新”的用法:
mutate('/api/user', newUser, false) // 使用 `false` 进行 mutate 无需重新验证mutate('/api/user', updateUser(newUser)) // `updateUser` 是请求的 Promise, // 返回 updated document
Mutate Based on Current Data(根据当前数据更改)
有时,你想基于当前数据更新部分你的数据。
使用 mutate
,你可以传递一个异步函数,该函数将接收当前缓存的值(如果有的话),并返回一个 updated document。
mutate('/api/todos', async todos => { // 把 ID 为 1 的更新为 completed, // 该 API 返回更新后的数据 const updatedTodo = await fetch('/api/todos/1', { method: 'PATCH', body: JSON.stringify({ completed: true }) }) // 筛选列表,返回更新后的 item const filteredTodos = todos.filter(todo => todo.id !== '1') return [...filteredTodos, updatedTodo]})
Returned Data from Mutate
最有可能的是,你需要一些数据来更新缓存。这些数据是从你传递给 mutate
的 promise 或 异步函数解析或返回的。
该函数将返回一个 updated document,让 mutate
更新相应的缓存值。每次调用它时,都可能以某种方式抛出错误。
try { const user = await mutate('/api/user', updateUser(newUser))} catch (error) { // 在这里处理更新 user 时的错误}
Bound Mutate
useSWR
返回的 SWR 对象还包含一个 mutate()
函数,该函数预先绑定到 SWR 的 key。
它在功能上等同于全局 mutate
函数,但不需要 key
参数。
import useSWR from 'swr'function Profile () { const { data, mutate } = useSWR('/api/user', fetcher) return ( <div> <h1>My name is {data.name}.</h1> <button onClick={async () => { const newName = data.name.toUpperCase() // 向 API 发送请求以更新数据 await requestUpdateUsername(newName) // 立即更新本地数据并重新验证 (重新请求) // 注意:在使用 useSWR 的 mutate 时,key 是不需要的,因为它是预先绑定的 mutate({ ...data, name: newName }) }}>Uppercase my name!</button> </div> )}