xxleyi / learning_list

聚集自己的学习笔记
11 stars 3 forks source link

data fetch in react #337

Open xxleyi opened 1 year ago

xxleyi commented 1 year ago

react 中的异步数据获取似乎要迎来一些变化了。

Reading the result of a promise that was read previously

If props or state have changed, React can't assume that a promise passed to use has the same result as the previous attempt. We need a different strategy.

The first thing React will try is to check if the promise was read previously, either by a different use call or a different render attempt. If so, React can reuse the result from last time, synchronously, without suspending.

React does this by adding additional properties to the promise object:

The status field is set to one of "pending", "fulfilled", or "rejected". When a promise is fulfilled, its value field is set to the fulfilled value. When a promise is rejected, its reason field is set to the rejection reason (which in practice is usually an error object). (The naming of these fields is borrowed from Promise.allSettled.)

Keep in mind that React will not add these extra fields to every promise, only those promise objects that are passed to use. It does not require modifying the global environment or the Promise prototype, and will not affect non-React code.

Although this convention is not part of the JavaScript specification, we think it's a reasonable way to track a promise's result. The ideal is that the lifetime of the resolved value corresponds to the lifetime of the promise object. The most straightforward way to implement this is by adding a property directly to the promise.

An alternative would be to use a WeakMap, which offers similar benefits. The advantage of using a property instead of a WeakMap is that other frameworks besides React can access these fields, too. For example, a data framework can set the status and value fields on a promise preemptively, before passing to React, so that React can unwrap it without waiting a microtask.

If JavaScript were to ever adopt a standard API for synchronously inspecting the value of a promise, we would switch to that instead. (Indeed, if an API like Promise.inspect existed, this RFC would be significantly shorter.)

这意味着,React 将提供官方 API,让框架和用户使用,实现组件渲染时,能够同步读取 Promise 中结果的效果。这具体意味着什么呢?我基于别人的一个 demo,自己改了改,实现了一个最简单的 cache + prefetch + 同步渲染 Promise 的效果。

具体见:https://codesandbox.io/s/suspense-use-demo-forked-from-zustand-suspense-demo-dq3i7h-yd3vlg?file=/src/App.js

未来大概的局面是,prefetch 成为标配,loading 管理变得轻松,大量无效 loading 不再出现,必要的 loading 真正发挥作用,而不是有碍观瞻,无脑 loading。