如何延迟 React 渲染子组件直到父组件完成获取?
我有一个从 webAPI 获取的父组件,它将返回一个人员数组。 我还有一个子组件,它应该从父组件接收 props,其中 props 是从获取中获得的
我遇到的问题是,React 似乎在获取完成之前渲染了子组件。 这是我的代码:
import React from "react";
import { Person} from "./Components";
export function Body({departmentId}){
const [peopleArray,setPeopleArray] = React.useState([]);
React.useEffect(
() => {
const getPeopleArr = async () => {
const response = await
fetch(`https://xxxx`);
const data = await response.json();
setPeopleArray(data);
};
getPeopleArr();
}, []);
return(
<div>
<Person name={peopleArray[0].personalDetails.name} position={peopleArray[0].department.name}/>
</div>
);
}
从上面可以看出,最初 peopleArray 是一个空数组。如果我删除代码
<Person name={peopleArray[0].personalDetails.name} position={peopleArray[0].department.name}/>,React 将给我错误“Uncaught TypeError: Cannot read properties of undefined (reading 'personalDetails')”
等待一段时间,直到它提取完毕,然后快速粘贴代码,它会成功显示 Person 组件。
我尝试在子组件中添加 SetTimeOut 并尝试将其延迟几秒钟,方法是:
setTimeout(() => {
}, "2000")
但这似乎对问题没有帮助。
您能否建议我可以做些什么来延迟子组件在提取完成之前呈现? 谢谢
编辑: 我能想到的一件事是为我想传递给子组件的每个 props 创建多个 useState,例如
const [name,SetName] = data[0].personalDetails.name;
...
<Person name = {name}>
但如果我有 20 个 props 需要传递,那么我必须创建 20 个 useState
编辑:?有效......谢谢大家 :D
有几种方法可以解决这个问题。
最简单的方法是使用可选链。类似这样的方法:
<Person name={peopleArray[0]?.personalDetails?.name} position={peopleArray[0]?.department?.name}/>
如果
peopleArray[0]
未定义,则不会渲染任何内容
另一种解决方案是使用长度:
peopleArray.length > 0 && <Person name={peopleArray[0].personalDetails.name} position={peopleArray[0].department.name}/>
第三个方法是引入加载状态,默认情况下可以为 true,您可以在
fetch
承诺解决后将其更改为 false
您应该首先检查变量是否不为空:
{peopleArray.length && <Person name={peopleArray[0]?.personalDetails.name} position={peopleArray[0]?.department.name}/> }
只需引入“loaded”之类的状态,然后有条件地呈现您的子组件:
loaded && <ChildComponent />
对于您的情况:
import React from "react";
import { Person} from "./Components";
export function Body({departmentId}){
const [peopleArray,setPeopleArray] = React.useState([]);
const [loaded, setLoaded] = React.useState(false);
React.useEffect(
() => {
const getPeopleArr = async () => {
const response = await
fetch(`https://xxxx`);
const data = await response.json();
setPeopleArray(data);
};
await getPeopleArr();
setLoaded(true);
}, []);
return(
<div>
{loaded && <Person name={peopleArray[0].personalDetails.name} position={peopleArray[0].department.name}/>}
</div>
);
}