条件渲染不等待获取完成

Conditional Rendering not waiting for Fetch to Complete

在应用程序中,我从 Firebase/Firestore 获取数据,将其解析为接口并将 object 添加到状态数组。之后我想渲染它。但是反应不会渲染数组。我已经评论了代码,你可以看到我认为它应该做什么。

const Tab1: React.FC = () => {

  let spiceArray: singleSpice[] = [];

  interface singleSpice {
    spice: string,
    grams: number,
  }

 

  useEffect(() => {
    //fetch the data --> Works well
    async function loadData() {
      const data = await getCollections();
    // Add the Data to the Spicearray --> Works  
      data.forEach((e: any) => spiceArray.push(e));
    }
    // Trigger Function onComponentMount
    loadData();
    // This function will never log "Worked" even tho the loadData is Async
    if(spiceArray.length > 0){
      console.log("Worked")
    }
    
  })



  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>Tab 1</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent fullscreen>
        <IonHeader collapse="condense">
          <IonToolbar>
            <IonTitle size="large">Tab 1</IonTitle>
          </IonToolbar>
        </IonHeader>
        //Transfer the spiceArray to the next Child as Props --> Works
        <CustomTab1 spices={spiceArray}/>
        <ExploreContainer name="Tab 1 page" />
        <IonButton onClick={() => console.log(spiceArray.length)}> Test me</IonButton>
        
      </IonContent>
    </IonPage>
  );
};

export default Tab1;

Child

    //Interface for Props
    interface Props {
        spices: Spice[];
    }
    //Interface to get access to inner Attributes of the SpiceObjectArray
    interface Spice {
        spice: string;
        grams: number;
    }
    
    const CustomTab1: React.FC<Props> = ({spices}: Props) => {
        return (
        <IonList>
            //Conditional Render 
            {spices.length > 0 && spices.map(entry => <IonItem id={entry.spice}>{entry.spice}</IonItem>)}
            <IonButton onClick={() => console.log(spices)}>Test</IonButton>
        </IonList>
    
        );
      };
    
      export default CustomTab1;

疯狂的事情是。现在,当我按 F5 时,会显示香料的 IonicApp none。但是,当我更改 CustomTab1-Component 上 IoNButton 内的文本并保存简单的更改时,香料将被渲染。但是如果我按 F5 刷新应用程序,一切都消失了 again.How 我可以让应用程序等到 API 传送数据吗?

spiceArray 不是状态,无法重新呈现您的子组件。

将您的变量更改为状态

当变量改变时,React 不会重新渲染。你说你正在将获取的对象传递给“状态数组”但是 spiceArray 不是一个反应状态。在功能组件中,状态是用 useState 声明的。

当您的页面最初加载时,没有数据,您的想法是正确的,在尝试映射 over/render 之前先检查是否有任何数据。但是为了让组件重新渲染并因此重新检查 spicesArray 中是否有任何内容,您必须使用状态并更改状态。

const [spiceArray, setSpiceArray] = useState<singleSpice[] | null>(null)
  useEffect(() => {
    //fetch the data --> Works well
    async function loadData() {
      const data = await getCollections();
    // Add the Data to the Spicearray --> Works  
     setSpiceArray(data)
    }
    // Trigger Function onComponentMount
    loadData();
    
    // This function will never log "Worked" even tho the loadData is Async
    if (spiceArray.length > 0) {
      console.log("Worked");
    }
  }, []);

您的代码应如下所示 并将子组件渲染逻辑更改为:

{spices && spices.map(entry => <IonItem id={entry.spice}>{entry.spice}</IonItem>)}

请记住其他几件事:

  1. 如果你希望 useEffect 只在挂载时 运行(这通常是在获取数据时的情况),你需要一个空的依赖数组。
  2. 控制台记录 spiceArray 或检查 spiceArray.length 是否不为 0 在 useEffect 中仍然不起作用,因为反应中的状态更新是异步的/为下一个渲染更新状态的请求。因此,更改不会立即反映/观察到

您不用等待 loadData(); 吗?

然后继续if(spiceArray.length > 0){