许多文章写了如何返回挂起的承诺并使用 React Suspense,但它在现实世界中不起作用。 他们不考虑组件是否被第二次访问,并且不会从服务器重新获取数据。
例如=> https://dev.to/darkmavis1980/a-practical-example-of-suspense-in-react-18-3lln?signin=true
下面的示例仅在我们第一次访问该组件时有效,但在接下来的时间中不会重新获取数据。
有什么想法让它发挥作用以防止不重新获取吗?
const dataFetchWithWrapPromise = (url) => {
return wrapPromise(window.fetch(url, {
}));
}
const resource = dataFetchWithWrapPromise('http://localhost:3000/data');
function Articles() {
const data = resource.read();
React.useEffect(() => {
return () => {
resource.reset();
}
}, []);
return (
<>
<h1>Data</h1>
<pre>
{JSON.stringify(data, null, 4)}
</pre>
</>
);
}
export default Articles;
function wrapPromise(promise) {
let status = 'pending';
let response;
const suspender = promise.then(
async res => {
status = 'success';
response = await res.json();
},
err => {
status = 'error';
response = err;
},
);
const handler = {
pending: () => {
throw suspender;
},
error: () => {
throw response;
},
success: () => {
console.log(response)
return response
},
default: () => {
throw suspender;
},
};
const read = () => {
const result = handler[status] ? handler[status]() : handler.default();
return result;
};
const reset = () => {
if(status!=='pending') {
status = 'pending';
response = undefined;
}
}
return { read, reset };
}
export default wrapPromise;
好的,我想我已经帮您解决了。 正好我一听说就喜欢
<Suspense>
。 我在学习异步 JavaScript 时偶然发现了它,因为我正在编写 wj-config。 这篇序言只是为了让你知道我不是 React 大师,但碰巧我最终为 wj-config v2.0.0 创建了一个 React 示例,该示例目前处于 BETA 2 中。这个示例做了你想要的事情想要。
所以不要再闲聊了。 感兴趣的代码是这里。
它是一个从Mockaroo加载人员数据的表格组件。 网页(父级)有两个控件来指定所需的行数以及所需的最小出生日期。 每当这些控件中的任何一个的值发生更改时,都会重新获取人员数据。 表格本身在两个地方使用了
<Suspense>
。
组件模块首先定义个人和国家数据所需的获取函数。 然后它声明了一些稍后在作用域中捕获的变量。 第一次渲染需要起始承诺。 它的解析器通过
startingResolver
公开,并且起始承诺按照您清楚知道的 <Suspense>
机制进行包装。
现在将注意力集中在
PersonsTable
功能上。 它设置一个 useEffect
调用来根据 props 的变化重新触发数据获取操作。 由于我不是 ReactJS 的超级大师,也许有比 props 更好的方法。 我只知道道具会自动触发效果,所以我就用了它们。
在第一次渲染时,起始承诺被抛出,但它永远不会被实现,因为它是一个虚假的承诺。
useEffect
中的代码使此 Promise 在 fetching Promise 解析的同时解析。 然后,使用获取承诺,定义了 readPersons
函数。
注意:我的母语不是英语。 请原谅我可怕的“人”而不是“人”的错误。 :-( 只要有时间我就会纠正。
无论如何,有了这个设置,你就完成了你的目标。 链接的代码示例超越了这一点,它有一个内部
<Suspense>
等待国家/地区数据,但我认为不需要解释,因为我相信问题现在已经涵盖了。
希望这有帮助!