【发布时间】:2021-01-22 07:45:20
【问题描述】:
我正在尝试使用实验性的新 React 功能 Suspense for data fetching。
这是我的简单 useApi 钩子(如果我正确理解 Suspense)要么返回 fetch 调用的结果,要么抛出吊杆承诺。 (稍作修改the documented example)
function useApi(path) {
const ref = React.useRef({ time: +new Date() });
if (!ref.current.suspender) {
ref.current.suspender = fetch(path).then(
data => ref.current.data = data,
error => ref.current.error = error,
);
}
if (ref.current.data) return ref.current.data;
if (ref.current.error) return ref.current.error;
throw ref.current.suspender;
}
我就是这样使用这个钩子的:
function Child({ path }) {
const data = useApi(path);
return "ok";
}
export default function App() {
return (
<Suspense fallback="Loading…">
<Child path="/some-path" />
</Suspense>
);
}
它永远不会解决。
我认为问题在于 useRef 并没有按预期工作。
如果我用一个随机值初始化 ref,它不会保留那个值,而是用另一个随机值重新初始化:
const ref = React.useRef({ time: +new Date() });
console.log(ref.current.time)
1602067347386
1602067348447
1602067349822
1602067350895
...
抛出 suspender 会导致 useRef 在每次调用时重新初始化,这有点奇怪。
throw ref.current.suspender;
如果我删除该行 useRef 按预期工作,但显然 Suspense 不起作用。
另一种让它工作的方法是,如果我在 React 之外使用某种自定义缓存,例如:
const globalCache = {}
function useApi(path) {
const cached = globalCache[path] || (globalCache[path] = {});
if (!cached.suspender) {
cached.suspender = ...
}
if (cached.data) ...;
if (cached.error) ...;
throw cached.suspender;
}
这也使它工作,但我宁愿使用 React 本身在缓存组件特定数据方面提供的东西。
我是否遗漏了关于 useRef 应该如何使用或不应该如何使用 Suspense 的内容?
【问题讨论】:
标签: reactjs react-suspense use-ref