【问题标题】:populate array variable from json url without promise [duplicate]从没有承诺的json url填充数组变量[重复]
【发布时间】:2021-09-30 12:16:17
【问题描述】:

嗨,我正在尝试通过将所有数据输入到数组变量中来显示来自 ReactJS 中的 json url 的数据,但我不能在 JSX 部分中使用该数组,因为在渲染时该数组尚未填充我尝试' d 很多事情,但我总是陷入一个承诺循环,我需要一个承诺来从另一个人那里获取数据。 代码:

let arry = [];
  let ar = [];

  async function getdriver() {
    const response = await fetch("https://ergast.com/api/f1/current/drivers.json");
    ar = await response.json();
    ar.MRData.DriverTable.Drivers.forEach((element) => {
      arry.push(element);
    });
    return arry;
  }

  getdriver();

  console.log(arry);// the array is populated but i think it waits for it before showing
  console.log(arry.lenght); //lenght is 0

JSX:

return (
    <div>
      <Menu />
      <div style={{ textAlign: "left" }}>
        <h4>ff</h4>
        <Button >change</Button>
        <br></br>
        <i>{arry[0].code}</i>// error ' Cannot read property 'code' of undefined ' so arry is empty? 
      </div>
    </div>
  );

【问题讨论】:

  • 不返回数组,而是将数据保存在组件的状态和JSX内部,对保存在状态的数组使用map()方法。见:Using the State Hook
  • 那里发生了一些“特殊”的事情:)。你需要awaitgetdriver()方法。

标签: javascript reactjs promise jsx fetch-api


【解决方案1】:

获取数据是一个副作用,然后你需要将这个数据存储为state,所以你需要使用两种hooks(假设你正在创建function components):

您的异步代码将在useEffect 中调用,调用完成后您将使用useState 将结果保存为组件的状态。

代码将类似于下面的示例(我尽可能多地保留了您的代码,但重命名了一些函数和变量,并添加了一些 cmets,以使其对尽可能多的其他读者有用):

import { useState, useEffect } from "react";

// this can exist outside the component
// it can even be in a different file
async function fetchDrivers() {
  const response = await fetch(
    "https://ergast.com/api/f1/current/drivers.json"
  );
  const data = await response.json();
  return data.MRData.DriverTable.Drivers;
}

function YourComponent() {
  // we declare the state, initially it's an empty array
  const [drivers, setDrivers] = useState([]);

  // we declare the effect that runs exactly once,
  // when the component is mounted
  useEffect(() => {
    fetchDrivers().then(setDrivers);
  }, []);

  // we print the code for all drivers
  // mapping the drivers array to JSX.
  // notice the key attribute, this is required with map
  // to uniquely identify each element
  return (
    <div>
      <Menu />
      <div style={{ textAlign: "left" }}>
        <h4>ff</h4>
        <Button>change</Button>
        <br></br>
        {drivers.map((driver, index) => (
          <p key={index}>
            <i>{driver.code}</i>
          </p>
        ))}
      </div>
    </div>
  );
}

【讨论】:

  • 非常感谢这有效,我明白我必须做什么。谢谢大家的帮助
【解决方案2】:

如果您想在第一次渲染时显示从 API 获取的数据,您应该将 API 调用放入 useEffect 并提供一个空数组作为 useEffect 的依赖项,同时将数组设置为状态值:

 import {useState, useEffect} from 'React';

 function YourComponent(){
  const [array, setArray] = useState([]);

  useEffect(()=>{getDriver().then((array)=>
  {setArray(array)})}
  ,[])
 }

这只是一个示例,在getDriver() 中,在您获得 API 调用的结果后,您应该使用 setState() 设置 array 以告诉 React 在该值更改后重新渲染,但当您将它放在这里时在useEffect 中只会在第一次渲染时触发。

【讨论】:

    猜你喜欢
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-19
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    相关资源
    最近更新 更多