key参数的选择

useSWRkey参数作为数据的唯一标识,能够完成的功能还有很多。SWR会将key参数赋予fetcher函数作为参数,所以在选择key参数的时候通常都是使用所需要访问的数据提供端的URL。但是除了字符串类型的key以外,null、函数、数组都可以作为key来使用,而且根据这些类型的key,还可以实现很多更高级的特性。

如果key使用了null或者函数,那么在keynull或者函数抛出错误的时候,fetcher函数将不会被启动。例如:

// 使用三元表达式来进行有条件的请求
const { data } = useSWR(shouldFetch ? '/api/usr' : null, fetcher);

// 使用Lambda表达式返回一个假值来进行有条件的请求
const { data } = useSWR(() => (shouldFetch ? '/api/usr' : null), fetcher);

// 或者直接让作为key的函数抛出错误
const { data } = useSWR(() => '/api/usr?id=' + user.id, fetcher);

当传递一个函数作为key的时候,SWR会使用其返回值来作为真正的key,如果在这个函数中使用了其他SWR返回的数据,那么SWR就会等待其他的请求完成,这样就形成了数据请求之间的依赖关系。例如以下示例。

function Orders() {
  const { data: user } = useSWR('/api/usr');
  const { data: orders } = useSWR(() => 'api/orders?uid=' + user.id);

  if (!orders) return 'Loading';
  return <div>{order.length} Orders found.</div>;
}

当数组作为key参数的时候,SWR所获取的数据就会与其中的每一个数据相关联。

例如使用数组来作为key

const fetcher = (url, token) => fetch(url, { method: 'post', body: { token: token } }).then(res => res.json);

function User() {
  const { data: user } = useSWR(['/api/usr', token], fetcher);

  // 处理其他的逻辑
}

在进行判断的时候,SWR会使用浅比较来跟踪key中成员的变化。所以如果在key中使用数组,那么其中的成员就需要保持一定的稳定性,因为任何值的变化,都将会导致SWR重新获取数据。例如以下两种请求。

// 以下这种请求是不对的,SWR会认为key一直在变化
const { data } = useSWR(['/api/usr', { id }], fetcher);

// 使用比较稳定的值才会有效果
const { data } = useSWR(['/api/usr', id], (url, id) => fetcher(url, { id }));