0
import React, { useEffect, useState } from "react";
import { useGetTeamQuery } from "./store/teamsApi"


function TeamList(props) {
    const team_names = []
    console.log("GET ALL TEAMS", props.props.items)
    

    useEffect(() => {
        const fetchData = async () => {
            for (let i = 1; i < 31; i++) {
                const res = await fetch(
                    `http://sports.core.api.espn.com/v2/sports/football/leagues/nfl/seasons/2022/teams/${i}?lang=en&region=us`
                    );
                const json = await res.json();
                console.log("JSON", json)
                team_names.push(json.displayName)
        }};
        fetchData();

        }, [team_names]);
    console.log("DATA", team_names)


    return (
        <>
        <div className="container">
            <h1>Team List</h1>
            <div>
            <ol>
                {console.log("DATA 2", team_names)}
                {team_names.map(team => (
                    <li>{team}</li>
                ))}
            </ol>
            </div>
        </div>
        </>
    )
}


export default TeamList;

There are no errors, but no code being rendered outside of the tags.

Have tried using numerous tags, and tried different changes to the useeffect function as well. Because list appears as intended is the "DATA 2" console.log, my thinking is the issue is the block of code below this. I'm not sure how to reformulate this map:

                {team_names.map(team => (
                    <li>{team}</li>
                ))}
granco20
  • 21
  • 3
  • [react-hook-warnings-for-async-function-in-useeffect-useeffect-function-must-ret](https://stackoverflow.com/questions/53332321/react-hook-warnings-for-async-function-in-useeffect-useeffect-function-must-ret) – Ryan Wilson Dec 09 '22 at 20:29
  • 2
    `team_names` should be stored in state if you want changes to it to cause a re-render. Look at `useState` hook. `console.log` of arrays will show the right thing because when you console.log an object, it's logging a reference to it. So as the array updates, the console log will appear correct. But this doesn't cause any state updates to happen so your UI will be out of sync with the actual content of the array. – noodlejs Dec 09 '22 at 20:43

1 Answers1

1

You should use useState to save the response from the API.

So here's your solution:

import React, { useEffect, useState } from "react";
import { useGetTeamQuery } from "./store/teamsApi";

function TeamList(props) {
  const [team_names, setTeam_names] = useState([]);

  useEffect(() => {
    let arr = [];
    async function fetchData() {
      try {
        for (let i = 1; i < 31; i++) {
          const response = await fetch(
            `https://sports.core.api.espn.com/v2/sports/football/leagues/nfl/seasons/2022/teams/${i}?lang=en&region=us`
          );
          const json = await response.json();
          arr.push(json.displayName);
        }
      } catch (e) {
        console.error(e);
      }
      setTeam_names(arr);
    }
    fetchData();
  }, []);

  return (
    <>
      <div className="container">
        <h1>Team List</h1>
        <div>
          <ol>
            {team_names.map((team, i) => (
              <li key={i}>{team}</li>
            ))}
          </ol>
        </div>
      </div>
    </>
  );
}

export default TeamList;

It's live in the codesandbox: https://codesandbox.io/s/admiring-liskov-1vmzd7?file=/src/TeamList.js

DreamBold
  • 2,727
  • 1
  • 9
  • 24
  • 1
    Great answer! But won't this cause 30 rerenders, one each time an api call is complete and updates the state? If you want it to only rerender once, you could push team_names to a temporary array that is declared before the for loop begins (let arr = []), and then update the state only when all api calls are complete: setTeam_names(arr) – sarahm16 Dec 10 '22 at 01:57