0

I am trying to fetch the Rick and Morty API and display an info card about each character. There are 826 characters in total separated in 42 pages. I am not sure how to fetch all different pages at once... so I came up with this for loop solution.

  const [characters, setCharacters] = useState([]);

  const fetchData = () => {
    let allCharacters = [];

    for (let i = 1; i <= 42; i++) {
      fetch(`https://rickandmortyapi.com/api/character?page=${i}`)
        .then((response) => {
          return response.json();
        })
        .then((data) => {
          allCharacters.push(data.results);
        });
    }
    setCharacters(allCharacters);
  };

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

The problem is that I am getting the desired data stored twice in the State and when looping through it to display the cards I get 1600 characters. Any suggestion how I could improve my fetching technic? The API structure looks like this:

{
  "info": {
    "count": 826,
    "pages": 42,
    "next": "https://rickandmortyapi.com/api/character?page=2",
    "prev": null
  },
  "results": [
    {
      "id": 1,
      "name": "Rick Sanchez",
...

I have seen this question already posted in stackoverflow but there they also get double the data... that is why I ask again and sorry for the similar post! Thanks!

Simon CF
  • 25
  • 1
  • 1
  • 8
  • Does this answer your question? [How to use fetch within a for-loop, wait for results and then console.log it](https://stackoverflow.com/questions/51012819/how-to-use-fetch-within-a-for-loop-wait-for-results-and-then-console-log-it) – Heretic Monkey Jul 18 '22 at 16:06
  • Thanks for you comment. It gives nice information. I am trying to adapt it to my project and see if it works... – Simon CF Jul 19 '22 at 06:10

1 Answers1

0

Solution was to adapt the useEffect. In modern React the component mounts, unmounts and mounts again... this is what I have read. To avoid the second mount I added the should fetch variable which will be changed to false after the first fetch, avoiding the second fetch to happen. To have in mind that this will only work if you have only one piece of state. If you are changing another state in the same component you will run into an infinite loop. useEffect(() =>

const [characters, setCharacters] = useState([]);
const shouldFetch = useRef(true);
  useEffect(() => {
    if (shouldFetch.current) {
      shouldFetch.current = false;
      fetchData("https://rickandmortyapi.com/api/character");
    }
  }, []);

  const fetchData = async (url) => {
    const res = await fetch(url);
    const data = await res.json();
    setCharacters((characters) => {
      console.log(characters);
      return [...characters, ...data.results];
    });
    if (data.info && data.info.next) {
      fetchData(data.info.next);
    }
  };
Simon CF
  • 25
  • 1
  • 1
  • 8