开发者问题收集

如何延迟 React 渲染子组件直到父组件完成获取?

2022-05-26
3647

我有一个从 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

3个回答

有几种方法可以解决这个问题。

最简单的方法是使用可选链。类似这样的方法:

<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

Chibuokem Onyekwelu
2022-05-26

您应该首先检查变量是否不为空:

{peopleArray.length && <Person name={peopleArray[0]?.personalDetails.name} position={peopleArray[0]?.department.name}/> }
M't
2022-05-26

只需引入“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>
    );
}
Igor Gonak
2022-05-26