skip to Main Content

I’m trying to make a Rick & Morty API call with fetch and an async arrow function, but I found that the function is pushing the elements received twice into my array.
I already tried to make the call with and without useEffect (I’m using React with TypeScript) but I got no results and I don’t understand why the function is being called twice.

Anyone available to explain to me why this is happening?

data.ts:

import { PlanetInterface, ResidentsInterface } from "./data-interfaces";

export const planetsList: PlanetInterface[] = [];
export const residentsList: ResidentsInterface[] = [];

export const getPlanetById = async (planets: number[]) => {
  for (let planet of planets) {
    const response = await fetch(
      `https://rickandmortyapi.com/api/location/${planet}`
    );
    const planetData: PlanetInterface = await response.json();
    planetsList.push(planetData);
  }
  console.log(planetsList);
};

// export const getResidentsByPlanet = async (residents: string[]) => {
//   for (let resident of residents) {
//     const response = await fetch(resident);
//     const residentData = await response.json();
//     residentsList.push(residentData);
//   }
//   console.log(residentsList);
// };


app.tsx:

import { useEffect } from "react";
import { getPlanetById } from "./api/data";
import "./App.css";

function App() {
  useEffect(() => {
    getPlanetById([1, 2]);
  }, []);

  // getPlanetById([1, 2]);

  return <main className="container"></main>;
}

export default App;

Expected output: Array of 2 objects (planets with ID 1 and 2)

Received output: Array of 4 objects (planet with ID 1 twice and planet with ID 2 also twice)

If anyone can help me understand why this is happening and how I can fix it, I would be very grateful.

2

Answers


  1. I guess you are using <React.StrictMode />

    If you remove that, the function is called once as you expect.

    Here is the document about strict mode
    https://en.reactjs.org/docs/strict-mode.html

    Login or Signup to reply.
  2. The design of that getPlanetById might be not suit for React since the call of it create a side effect and there is no way to clean it up, you should wrap it into a hook or do a manually clean up, here is an example:

    useEffect(() => {
        getPlanetById([1, 2]);
        return () => { planetsList.length = 0 }
    }, []);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search