从 api 获取数据并创建对象后渲染卡片

Render Cards after fetch data from api and create an object

我正在尝试学习 ReactJS.. 今天我试图创建一个包含获取结果的对象数组,然后创建卡片,但我只能更新状态,但卡片不会重新渲染。你能帮我吗?

App.js

  const teamsForLoop = [
    Team1,
    Team2,
    Team3
  ];

  const [allPlayers, setAllPlayers] = useState([]);
  const [team, setTeam] = useState([]);
  const [allTeams] = useState(teamsForLoop);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const playerInfo = async() => {
      setLoading(true)
      allTeams.map(async(teamArray) => {
        setTeam([])
        teamArray.map(async (player) => {
          let playerName = player.split(" ");
          const result = await axios.get(
            `https://www.thesportsdb.com/api/v1/json/2/searchplayers.php?p=${playerName[0]}%20${playerName[1]}`
          );
          if (result.data.player === null) {
            setTeam((state) => {
              return [...state];
            });
          } else {
            setTeam((state) => {
              return [...state, result.data.player[0]];
            });
          }
        });
       setAllPlayers(team);
      });
      setLoading(false);
    };
    playerInfo();
  },[]);

  if (loading) return "...Loading...";

  return (
    <>
      <PlayerList allPlayers={allPlayers} />
    </>
  );
}

export default App;

PlayerList.js

function PlayerList({ allPlayers }) {
  const myData = []
  .concat(allPlayers)
  .sort((a, b) => (a.idTeam !== b.idTeam ? 1 : -1))
  return (
    <div>
      {myData.map((player,index) =>
        (
          <div key={index}>       
            ...........
            </div>
        )
      )}
    </div>
  );
}

我认为我的问题出在 useEffect 挂钩上,或者可能出在我的 fetch 函数上。 我已经使用数组但没有状态完成了它。

问题

我现在看到的问题是,您试图在循环中缓存处于 team 状态的抓取玩家,然后使用 team 状态更新 players 状态.这里的问题是 React 状态更新是异步处理的,所以调用 setAllPlayers(team);team 还没有更新。

解决方案

allTeams 数组映射到 GET 请求,等待它们解析,然后将单个 allPlayers 状态更新加入队列会更简单。展平团队球员的阵列并将它们映射到 axios GET Promise。等待这些解决并将结果映射到玩家数组。

示例:

function App() {
  const [allPlayers, setAllPlayers] = useState([]);
  const [allTeams] = useState(teamsForLoop);
  const [loading, setLoading] = useState(true);

  const playerInfo = async () => {
    setLoading(true);
    const response = await Promise.all(
      allTeams
        .flat()
        .map((player) =>
          axios.get(
            `https://www.thesportsdb.com/api/v1/json/2/searchplayers.php?p=${player}`
          )
        )
    );
    const players = response.map((result) => result.data.player[0]);
    setAllPlayers(players);
    setLoading(false);
  };

  useEffect(() => {
    playerInfo();
  }, []);

  if (loading) return "...Loading...";

  return <PlayerList allPlayers={allPlayers} />;
}