Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

182
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!