参数
默认情况下,key
将作为参数传递给 fetcher
。所以下面这3个表达式是等价的:
useSWR('/api/user', () => fetcher('/api/user'))useSWR('/api/user', url => fetcher(url))useSWR('/api/user', fetcher)
Multiple Arguments(多个参数)
在某些场景中,向 fetcher
函数传递多个参数(可以是任何值或对象)非常有用。例如授权请求:
useSWR('/api/user', url => fetchWithToken(url, token))
这是错误的。 因为数据的标识符(也是缓存 key)是 '/api/user'
,所以即使 token
变了,SWR 仍然会使用相同的 key 并返回错误的数据。
相反,你可以使用一个数组作为参数 key
,它包含 fetcher
的多个参数:
const { data: user } = useSWR(['/api/user', token], fetchWithToken)
fetchWithToken
函数仍然接受同样的2个参数,但现在缓存 key 也将与 token
相关联。
Passing Objects(传对象)
假设你还有另一个使用用户范围来请求数据的函数:fetchWithUser(api, user)
。你可以执行以下操作:
const { data: user } = useSWR(['/api/user', token], fetchWithToken)// ...并将其作为参数传递给另一个 queryconst { data: orders } = useSWR(user ? ['/api/orders', user] : null, fetchWithUser)
现在请求的 key 是两个值的组合。SWR 在每次渲染时浅比较参数,如果其中任何一个发生了变化,就会触发重新验证。
请记住,在渲染时不应该重新创建对象,因为每次渲染时它们将被视为不同的对象:
// 不要这样做!每次渲染时 Deps 都会变化。useSWR(['/api/user', { id }], query)// 相反,你应该只传递“稳定的”值。useSWR(['/api/user', id], (url, id) => query(url, { id }))
Dan Abramov 在这篇博客中很好地解释了依赖关系。