React Router:loader多fetch及返回对象时Promise问题解惑
关于React Router useLoaderData的两个问题解答
问题1:能否在loader中从多个URL获取数据并一次性返回?
当然可以,但你写的代码存在问题——res1.json()和res2.json()都是异步操作,调用后会返回Promise,你没加await的话,变量user和car存的就是未解析的Promise对象,不是接口返回的实际数据。
修正后的代码可以这样写:
export const userLoader = async () => { const res1 = await fetch('http://localhost:8000/user'); const user = await res1.json(); // 加await等待json解析完成 const res2 = await fetch('http://localhost:8000/car'); const car = await res2.json(); // 同样加await return { user, car }; }
如果想让两个请求并行发送、提升效率,还可以用Promise.all:
export const userLoader = async () => { // 同时发起两个请求 const [userRes, carRes] = await Promise.all([ fetch('http://localhost:8000/user'), fetch('http://localhost:8000/car') ]); // 分别解析返回结果 const user = await userRes.json(); const car = await carRes.json(); return { user, car }; }
这样组件里通过useLoaderData()拿到的就是包含实际数据的对象了。
问题2:为什么用{}包裹res.json()返回会得到Promise?
因为res.json()本身是异步方法,调用后会返回一个Promise对象。你直接写return { res.json() }时,没有用await等待这个Promise完成解析,所以返回的对象里对应的属性值就是这个未解析的Promise,而不是接口返回的JSON数据。
正确的写法是先await解析json,再放到对象里返回:
export const userLoader = async () => { const res = await fetch('http://localhost:8000/user'); const userData = await res.json(); // 先拿到实际解析后的数据 return { userData }; // 再把数据放入对象返回 }
或者也可以直接在对象属性中使用await:
export const userLoader = async () => { const res = await fetch('http://localhost:8000/user'); return { userData: await res.json() }; }
这样组件里就能拿到解析后的实际数据了。
内容的提问来源于stack exchange,提问作者kee
相关产品推荐
相关产品推荐

