首页 > 解决方案 > 将来自 API 的 fetch 调用中的数据附加到我的状态

问题描述

我在下面有这个函数,它在 forEach 循环中运行一个函数,如下所示:

async populateSystemData(id) {
    const response = await fetch('https://localhost:44389/api/systemlist/GetSystems/' + id);
    const data = await response.json();
    const result = Object.values(data);
    result.forEach((s) => {
        this.populatePlanetData(s.systemId);
    });
    this.setState({ systems: result, loading: false });
}

这是在循环内执行的函数:

async populatePlanetData(id) {
    const response = await fetch('https://localhost:44389/api/planetlist/GetPlanets/' + id);
    const data = await response.json();
    const result = Object.values(data);
    this.setState({ planets: result, loading: false });
}

这是我如何写出这些数据以便用户可以看到它:

{systems.map(s =>
    <tr>
        <td>{s.SystemName}</td>
        <td>
            <table>
                <tr>
                    <td>Planets</td>
                </tr>
                {planets.map(p =>
                    <tr>
                        <td>{p.PlanetName}</td>
                    </tr>
                )}                                      
            </table>
       </td>
    </tr>
 )}

更新 populatePlanetData 中的状态以使其追加而不是覆盖的最佳方法是什么?

谢谢!

标签: reactjsecmascript-6

解决方案


另一种更好地利用 React 组件的方法

根据作者的评论

there could be 200+ systems, with each system having 1 and up to 50 planets

与其循环遍历函数并使用一个全局状态进行加载,不如考虑拆分为组件。

从概念上讲,我们需要三个组件

  • 系统 - 加载所有系统并显示所有系统
  • 系统 - 从系统加载所有行星并显示行星
  • 星球 - 显示星球的内容

让我们继续执行它们

  1. 系统
function Systems({ id }) {
  const [systems, setSystems] = useState([]);

  useEffect(() => {
    const getSystems = async () => {
      const response = await fetch(
        `https://localhost:44389/api/systemlist/GetSystems/${id}`,
      );
      const data = await response.json();
      setSystems(Object.values(data));
    };
    getSystems();
  }, [id]);

  return (
    <table>
      {systems.map((system) => (
        <System system={system} />
      ))}
    </table>
  );
}
  1. 系统
function System({ system: { id, SystemName } }) {
  const [planets, setPlanets] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const getPlanets = async () => {
      const response = await fetch(
        `https://localhost:44389/api/systemlist/GetSystems/${id}`,
      );
      const data = await response.json();
      setPlanets(Object.values(data));
      setIsLoading(false);
    };
    getPlanets();
  }, [id]);

  return (
    <tr>
      {isLoading && <td>Loading...</td>}
      {!isLoading && (
        <>
          <td>{SystemName}</td>
          <td>
            <table>
              <tr>
                <td>Planets</td>
              </tr>
              {planets.map((planet) => (
                <Planet planet={planet} />
              ))}
            </table>
          </td>
        </>
      )}
    </tr>
  );
}
  1. 行星
const Planet = ({ planet: { PlanetName } }) => (
  <tr>
    <td>{PlanetName}</td>
  </tr>
);

您如何看待这种方法?


推荐阅读