SWR:改变数据时立即更新 UI
SWR: immediately update UI when mutating data
我希望 UI 中的数据立即更新,而不是等待 SWR 与数据库同步。
我试过关注 the docs,但 UI 仍然不会自动更新(我切换回浏览器进行更新)。这是代码:
import useSWR, { useSWRConfig } from "swr";
export default function Tasks() {
const { mutate } = useSWRConfig()
const { data } = useSWR("/api/tasks", (...args) =>
fetch(...args).then((res) => res.json())
)
const deleteTask = async (taskId) => {
const newData = data.filter((task) => task.id !== taskId)
mutate(`/api/tasks/${taskId}`, newData, false)
await fetch(`/api/tasks/${taskId}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
})
mutate(`/api/tasks/${taskId}`)
}
if (!data) return <p>loading</p>
return (
<div>
{data.map((task) => (
<div key={task.id}>
<div>{task.content}</div>
<button onClick={() => deleteTask(task.id)}>Delete</button>
</div>
))}
</div>
)
}
如果您阅读更多文档页面,您可以找到有界变异,它是由 useSWR 钩子返回的函数。这是重新验证数据的最简单方法。 doc
const { data, mutate } = useSWR('/api/user', fetcher)
...
mutate() //run mutation
问题是您调用了错误的 mutate 函数。当您在 mutate(`/api/tasks/${taskId}`)
上调用 mutate 时,您期望 data
得到刷新
首先进行如下修改
const { data, mutate: mutateList } = useSWR("/api/tasks", (...args) =>
fetch(...args).then((res) => res.json())
)
现在,在您的 delete task
中执行以下操作
const deleteTask = async (taskId) => {
const newData = data.filter((task) => task.id !== taskId)
// The useSWR("/api/tasks"...) returns a mutate method bound to swr's key, use it!
// Passing false will prevent revalidation so a fetch request
// won't be made to your api on the other hand if you pass true
// then a fetch request will be made to your api. In both cases
// you should see your cache refreshed immediately and that
// should update your UI. Since you haven't as yet updated your
// backend i.e. you are calling mutate _before_ calling your
// api, you'll want to pass false as 2nd argument.
// Had you called mutate after calling your api then you could
// have passed true as second argument to revalidate your cached
// data. Passing true as second argument in the function below
// doesn't make sense since you have yet to update your
// server/backend.
await mutateList(newData, false);
await fetch(`/api/tasks/${taskId}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
})
}
我希望 UI 中的数据立即更新,而不是等待 SWR 与数据库同步。
我试过关注 the docs,但 UI 仍然不会自动更新(我切换回浏览器进行更新)。这是代码:
import useSWR, { useSWRConfig } from "swr";
export default function Tasks() {
const { mutate } = useSWRConfig()
const { data } = useSWR("/api/tasks", (...args) =>
fetch(...args).then((res) => res.json())
)
const deleteTask = async (taskId) => {
const newData = data.filter((task) => task.id !== taskId)
mutate(`/api/tasks/${taskId}`, newData, false)
await fetch(`/api/tasks/${taskId}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
})
mutate(`/api/tasks/${taskId}`)
}
if (!data) return <p>loading</p>
return (
<div>
{data.map((task) => (
<div key={task.id}>
<div>{task.content}</div>
<button onClick={() => deleteTask(task.id)}>Delete</button>
</div>
))}
</div>
)
}
如果您阅读更多文档页面,您可以找到有界变异,它是由 useSWR 钩子返回的函数。这是重新验证数据的最简单方法。 doc
const { data, mutate } = useSWR('/api/user', fetcher)
...
mutate() //run mutation
问题是您调用了错误的 mutate 函数。当您在 mutate(`/api/tasks/${taskId}`)
data
得到刷新
首先进行如下修改
const { data, mutate: mutateList } = useSWR("/api/tasks", (...args) =>
fetch(...args).then((res) => res.json())
)
现在,在您的 delete task
中执行以下操作
const deleteTask = async (taskId) => {
const newData = data.filter((task) => task.id !== taskId)
// The useSWR("/api/tasks"...) returns a mutate method bound to swr's key, use it!
// Passing false will prevent revalidation so a fetch request
// won't be made to your api on the other hand if you pass true
// then a fetch request will be made to your api. In both cases
// you should see your cache refreshed immediately and that
// should update your UI. Since you haven't as yet updated your
// backend i.e. you are calling mutate _before_ calling your
// api, you'll want to pass false as 2nd argument.
// Had you called mutate after calling your api then you could
// have passed true as second argument to revalidate your cached
// data. Passing true as second argument in the function below
// doesn't make sense since you have yet to update your
// server/backend.
await mutateList(newData, false);
await fetch(`/api/tasks/${taskId}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
})
}