旧调新弹 - 使用 use 来获取数据
如果你问我:React 使用什么方式获取数据?我的回答是:用第三方库,例如 SWR 或者 React Query 之类的,再或者使用第三方框架自带的机制,例如 Remix Loader。
难道 React 没有自带的数据获取方式么?useEffect
不行么?
不太行,使用 useEffect
获取数据异常的麻烦,你需要:
- 处理成功、失败和 Loading 状态。
const [data, setData] = useState()
const [error, setError] = useState()
const [isLoading, setIsLoading] = useState()
同时,往往还需要在成功设置数据时,清空 error
,反之亦然。
-
处理 Race Condition。
-
区分空数据和初始数据。
const [data, setData] = useState([])
如果数据是一个列表,将初始值设置为空数组([]
),那将如何区分返回的空数据,还是初始值呢?往往此事,我们需要将初始值设置为 undefined
。
- 处理
useEffect
在触发两次问题。
一个「简单」的使用 useEffect
获取数据的代码如下:
这也就是为什么第三方数据获取库大行其道的重要原因,因为它们极大的简化了逻辑,同时也包含了 Cache、Prefetching、Middleware 等等常用的功能:
不过现在 React 团队推出了一个新的 Hook:use。
它结合 Suspence 和 Error Boundary 可以非常简单明了的处理成功、失败和 loading 状态。
同时也没有 Race Condition 等等问题。
- 我们可以把获取数据的
Promise
传入到use
中,返回值就是Promise
的 resolve 值,类似于await
一般
const data = use(dataPromise);
// 后续处理逻辑
// 类似
const data = await dataPromise;
// 后续处理逻辑
- 使用 Suspence 处理 Loading 状态; 使用 Error Boundary 处理 Error 状态。
- 也可以使用
Promise.catch
处理 Error 状态。
可以看到和上面 useEffect
的代码相比简化了非常多。
同时,一个 useEffect
和很多第三方库还无法完成的功能:use
也可以在 Server Components 和 Client Components 之间传递数据:
总结
不使用第三方库获取数据一直是一个老大难问题,现在我们可以考虑使用 use
,这也算第一个官方的「原生」获取数据方法。但是 use
并没有包含其他的高级功能:Cache、Prefetching、Middleware 等等在数据获取,或者可以称之为异步数据管理这个问题所必须的功能。