【问题标题】:How to update state of the component with data from API如何使用 API 中的数据更新组件的状态
【发布时间】:2021-06-30 20:57:06
【问题描述】:

我对 React 和 useState 有疑问。

我正在尝试下载所有characters from Star Wars API。我为此使用了 Axios,因此此代码仅用于导入 Axios 实例:

import { instance } from 'api/getCharacters';

您可以在 代码示例 中看到我有一个运行 getCharacters 异步函数的按钮,该函数在第一次调用时下载 10 个字符和 5 个字符在所有下一次呼叫(最后一次呼叫除外)。我将所有角色的 JSON 保存到 charactersArray。您还可以看到我将存储这些字符的状态变量传递给 CharactersList 组件。然后我只是映射字符数组,但这并不重要。我的问题是 - 如何使用 setCharacters 函数将状态更新为以前的状态?我知道我应该这样做:

setCharacters([...characters, charactersArray])

你能告诉我如果我没有错,并告诉我我应该在我的代码中的哪个位置执行上述表达式吗?

代码示例

import CharactersList from 'components/CharactersList/CharactersList';
import { Button } from 'components/Button/Button';
import { GlobalStyle } from 'styles/GlobalStyle';
import { Wrapper } from './Root.styles';
import { useState } from 'react';
import { instance } from 'api/getCharacters';

const Root = () => {
  const [characters, setCharacters] = useState([]);
  const charactersArray = [];
  const getCharacters = async () => {
    const loadedPeople = charactersArray.length;
    const maxPeople = 82;
    const perPage =
      loadedPeople === 80
        ? 2
        : loadedPeople >= maxPeople
        ? 0
        : loadedPeople < 10
        ? 10
        : 5;
    for (let index = loadedPeople; index < loadedPeople + perPage; index++) {
      const character = await instance.get(`${index + 1}`).catch((error) => {
        console.log(error);
        return error;
      });
      charactersArray.push(character.data);
    }
    console.log(charactersArray);
  };
  return (
    <Wrapper>
      <Button onClick={getCharacters}>Fetch</Button>
      <GlobalStyle />
      <CharactersList data={characters} />
    </Wrapper>
  );
};

export default Root;

谢谢

【问题讨论】:

    标签: javascript reactjs react-hooks use-state


    【解决方案1】:

    首先,遵循干净代码原则。

    并且 instance 不是 API 命名空间的已知关键字。 例如:您可以使用api().get('...')ApiCharachters.list()

    我不确定您的异步回调函数。使用前请阅读一些文章。

    我认为这样会更好:

    const MAX_PEOPLE = 82;
    
    function calcPerPage(loaded) {
      if (loaded === 80) return 2;
      else if (loaded >= MAX_PEOPLE) return 0;
    
      return loaded < 10 ? 10 : 5;
    }
    
    const Root = () => {
      const [characters, setCharacters] = useState([]);
    
      const handleGetCharacters = async () => {
        const loadedPeople = characters.length;
        const perPage = calcPerPage(loadedPeople);
    
        for (let i = loadedPeople; i < loadedPeople + perPage; i++) {
          const character = await instance.get(`${i + 1}`).catch((error) => {
            console.log(error);
            return error;
          });
    
          setCharacters((prev) => [...prev, character]);
        }
    
        console.log(characters);
      };
    
      return (
        <Wrapper>
          <Button onClick={handleGetCharacters}>Fetch</Button>
          <GlobalStyle />
          <CharactersList data={characters} />
        </Wrapper>
      );
    };
    
    

    【讨论】:

    • 记住,不要循环调用 setState。
    • 但是字符变量是const,所以我不能更新这个循环之外的状态,因为我的变量不可用。
    • 也许你可以将它推送到一个数组中,最后只调用一个 setState。
    • 我可以,但是循环内的 setState 是不好的做法,或者为什么我不应该在那里调用它?
    • 这是一种不好的做法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 2021-06-10
    • 2023-03-05
    • 1970-01-01
    • 2018-09-13
    • 2023-03-26
    • 2021-08-02
    相关资源
    最近更新 更多