我使用react router dom 6.14并尝试使用defere、suspense和await,就像在他们的文档中一样,无论我做什么,似乎后备从未呈现。
这是我的代码。
//route.tsx
const router = createBrowserRouter([
{
path: "/",
element: <App />,
errorElement: <ErrorPage />,
children: [
{
path: "/products/:category",
element: <ProductsMain />,
loader: (req) => getItems(req),
},
{
path: "/settings",
element: <SettingsComponent />,
},
],
},
{
path: "test",
element: <TestComonenet />,
errorElement: <ErrorPage />,
},
]);
//loader
export async function getItems(request: any, primaryStore: StoreEn, otherStores: StoreEn[]) {
// const body = getBodyFromStorage();
try {
const url = `${urlBE}/products/${request.params.category}`;
const data = serverAPI(url, body, "success"); // ===> its a promise
return defer(data:
} catch (error: any) {
throw new Error(error);
}
}
/// 服务器 api 上的快捷方式:
const serverAPI = async (url: productsEP, body: any, description?: string) => {
try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (!response.ok) {
const { message } = await response.json();
throw new Error(message);
}
const jsonData = await response.json();
return { data: jsonData, error: null, description: description };
} catch (error: any) {
throw new Error(error);
}
};
现在是 ProductsMain 组件:
const ProductsMain = () => {
const [products, setProducts] = useState<any[]>([]);
const data: any = useLoaderData();
return (
<Suspense fallback={<p>Loader...</p>}
<Await resolve={data} >
{(data) => (
<>
<Products data={data}/>
</>
)}
<Await />
</Suspense>
);
};
不知何故,加载程序似乎从未发生过。而且数据只是一个承诺,我无法渲染它(尽管我得到状态代码为 200 的数据)
对于此类问题,下面的代码可能会对您有所帮助。延迟应该按照您使用的方法来工作。因此,更改以下一些内容,可能会有效。
<React.Suspense fallback={<p>Loader...</p>}
<Await resolve={data} >
{(data) => (
<>
<Products data={data}/>
</>
)}
</div>
<Await />
</React.Suspense>
愿这对你有帮助。
将加载程序更改为以下内容..
//loader
export type GetItemsType = {
dataPromise: Promise<any>
}
export function getItems(request: any)
{
// const body = getBodyFromStorage();
const url = `${urlBE}/products/${request.params.category}`;
const deferredObj: GetItemsType = { dataPromise: serverAPI(url, body, "success") };
return defer(deferredObj);
}
请注意省略了
try-catch
语句,因为应在 Await
组件中捕获并处理错误。还删除了 async
修饰符,因为加载器中没有等待任何 Promise。
defer()
参数应该是一个对象,并且它的属性可以像这样访问..
import { GetItemsType } from 'PATH-TO-(GetItemsType)'
const ProductsMain = () =>
{
// const [products, setProducts] = useState<any[]>([]);
const data = useLoaderData() as GetItemsType;
<Suspense fallback={<p>Loader...</p>}
<Await resolve={data.dataPromise} errorElement={<p>*** Error Message here ***</p>} >
{
(data: any) => (<Products data={data}/>)
}
<Await />
</Suspense>
}
值得一提的是,我对
react-router-dom
的了解有些有限,我的回答是基于我所知道的,所以希望它有所帮助。