Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

181
Vistas
TypeError: Cannot read properties of undefined (reading 'map') even though useState() is initialized with array

I've got "TypeError: Cannot read properties of undefined (reading 'map')", even though useState() is initialized with array. The error occurs only in one component. Other components, which, I think, are also using useState and useEffect the same way, don't resolve with this error.

import { useState, useEffect } from "react/cjs/react.development";
import * as constants from "../../../../constants";

export default function Keywords(props) {
  const [movieKeywords, setMovieKeywords] = useState([]);

  useEffect(() => {
    const fetchKeywords = async () => {
      const data = await fetch(
        `${constants.TMDB_BASE_PATH}movie/${props.id}/keywords?api_key=${constants.API_KEY}`
      );

      const jsonData = await data.json();
      setMovieKeywords(jsonData.keywords);
      console.log("xdd");
    };

    fetchKeywords();
  }, []);
  return (
    <div className="flex flex-wrap">
      {movieKeywords.map((keyword) => {
        return (
          <div className="border font-oxygen m-1 rounded-xl cursor-pointer text-xs text-gray-300 px-2 py-1">
            <p>{keyword.name}</p>
          </div>
        );
      })}
    </div>
  );
}

I will be glad if anyone could point me in the right direction.

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

You're probably just off by just a few ms in the timing of the API call and the rendering. A good practice is to check for the existence of the array you're mapping before trying to render any JSX. Set your initial state to null and do optional chaining on your map line.

Refactor your component something like this:

import { useState, useEffect } from "react/cjs/react.development";
import * as constants from "../../../../constants";

export default function Keywords(props) {
  const [movieKeywords, setMovieKeywords] = useState();

  useEffect(() => {
    const fetchKeywords = async () => {
      const data = await fetch(
        `${constants.TMDB_BASE_PATH}movie/${props.id}/keywords?api_key=${constants.API_KEY}`
      );

      const jsonData = await data.json();
      setMovieKeywords(jsonData.keywords);
      console.log("xdd");
    };

    fetchKeywords();
  }, []);
  return (
    <div className="flex flex-wrap">
      {movieKeywords?.map((keyword) => {
        return (
          <div className="border font-oxygen m-1 rounded-xl cursor-pointer text-xs text-gray-300 px-2 py-1">
            <p>{keyword.name}</p>
          </div>
        );
      })}
    </div>
  );
}

Notice the movieKeywords?.map, this will not execute map until movieKeywords is not null, meaning it will wait until the fetch resolves and your state is set.

about 4 years ago · Juan Pablo Isaza Denunciar

0

"jsonData.keywords is not undefined." - The error is actually informing you that it is though. setMovieKeywords(jsonData.keywords); updates the state and then movieKeywords is undefined and unable to access a .map property/method.

From what I see, you are missing the props.id as a dependency for the useEffect and fetch. It sounds like props.id is initially not a valid value for the API request and you are getting an undefined keywords response.

You should only make the API request if you have all the required parameters, and your code should be robust enough to handle potentially invalid and bad responses.

  1. Add props.id to the useEffect hook's dependency array.
  2. Only make the fetch request if id is truthy.
  3. Handle potentially rejected Promises from fetch.
  4. Handle any potential bad state updates with undefined values.

Example:

import { useState, useEffect } from "react/cjs/react.development";
import * as constants from "../../../../constants";

export default function Keywords({ id }) {
  const [movieKeywords, setMovieKeywords] = useState([]);

  useEffect(() => {
    const fetchKeywords = async (id) => {
      try { // <-- (3) use try/catch to handle rejected Promise or other exceptions
        const data = await fetch(
          `${constants.TMDB_BASE_PATH}movie/${id}/keywords?api_key=${constants.API_KEY}`
        );

        const jsonData = await data.json();

        if (jsonData) { // <-- (4) only update state if defined response value
          setMovieKeywords(jsonData.keywords);
        }
      } catch(error) {
        // handle any errors, log, set error state, ignore(?), etc...
      }

      console.log("xdd");
    };

    if (id) { // <-- (2) only fetch if `id` is truthy
      fetchKeywords(id);
    }
  }, [id]); // <-- (1) add `id` as dependency

  return (
    <div className="flex flex-wrap">
      {movieKeywords?.map((keyword) => { // <-- Use Optional Chaining in case `movieKeywords` becomes falsey for any reason
        return (
          <div className="border font-oxygen m-1 rounded-xl cursor-pointer text-xs text-gray-300 px-2 py-1">
            <p>{keyword.name}</p>
          </div>
        );
      })}
    </div>
  );
}
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda