Gurjeet Singh
Gurjeet Singh

Reputation: 5

TypeError: Cannot read property 'map' of null React.js

Movie.js

This is my React Component throwing error of map property Cannot read. it just happen when I refresh page, means at first render, however when I comment & uncomment map function it get proper results and render my data to DOM, if refresh page it shows error I think My DOM render before getting data. Also used axios but same results. I struggling with it from 4 days. Thank You

import React,{useState, useEffect} from "react";
// import axios from "axios";
// import Datacard from './Datacard';

function Movie (){
    const [movieData, setmovieData] = useState(null);
    useEffect(()=>{
        getdata2()
    },[]);
    function getdata2(){
        fetch('https://api.themoviedb.org/3/trending/movie/day?api_key=91d216ec6cb5cb93f831efa4ca831725')
        .then(async(res) => await res.json())
        .then((data)=>{setmovieData(data.results);console.log(data.results)})
    }
    return(<>
            <div>
                <p>safsdfasdfd</p>
                {movieData.map(value=>(<div>{value.title}</div>))} //if I just comment & uncomment this part I get proper results, but when I refresh page I get error  
            </div>
        </>
    );
}
export default Movie;
                                                                          

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter} from 'react-router-dom';
import './index.scss';
import Movie from './Movie';
// import App from './App';`

ReactDOM.render(
  <>
  <BrowserRouter>
  <Movie/>
  </BrowserRouter>
  </>,
  document.getElementById('root')
);

console error

Movie.js:17 Uncaught TypeError: Cannot read property 'map' of null
    at Movie (Movie.js:17)
    at renderWithHooks (react-dom.development.js:14985)
    at mountIndeterminateComponent (react-dom.development.js:17811)
    at beginWork (react-dom.development.js:19049)
    at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
    at invokeGuardedCallback (react-dom.development.js:4056)
    at beginWork$1 (react-dom.development.js:23964)
    at performUnitOfWork (react-dom.development.js:22776)
    at workLoopSync (react-dom.development.js:22707)
    at renderRootSync (react-dom.development.js:22670)
    at performSyncWorkOnRoot (react-dom.development.js:22293)
    at scheduleUpdateOnFiber (react-dom.development.js:21881)
    at updateContainer (react-dom.development.js:25482)
    at react-dom.development.js:26021
    at unbatchedUpdates (react-dom.development.js:22431)
    at legacyRenderSubtreeIntoContainer (react-dom.development.js:26020)
    at Object.render (react-dom.development.js:26103)
    at Module.<anonymous> (index.js:8)
    at Module../src/index.js (index.js:10)
    at __webpack_require__ (bootstrap:851)
    at fn (bootstrap:150)
    at Object.1 (index.scss?7975:82)
    at __webpack_require__ (bootstrap:851)
    at checkDeferredModules (bootstrap:45)
    at Array.webpackJsonpCallback [as push] (bootstrap:32)
    at main.chunk.js:1

Upvotes: 0

Views: 2480

Answers (3)

Ivan Baev
Ivan Baev

Reputation: 33911

Fix: You need to set initial value in useState. Instead null set empty array ([]), cause .map is function for arrays.

const [movieData, setmovieData] = useState([]);

Or check for null with movieData?

 {movieData?.map(value=>(<div>{value.title}</div>))}

Or

{movieData === null
      ? "Loading..."
      : movieData.map(....)}

Theory: Please take a look the image below. There is the lifecycle of react components. enter image description here --- Mounting // first column

  1. Mount the component Movie
  2. Initialize movieData with null
  3. Execute useEffect but this is async function
  4. Render the return - ERROR appear here. You just pass null for movieData and you cannot perform .map on null it looks like null.map(....)

---Updating // the second column

  1. When you get result from fetch, React automatically perform update and re-render component again with array [mov1, mov2, mov3] then you can perform .map() funciton

Thanks, Ivan

Upvotes: 1

Rob Bailey
Rob Bailey

Reputation: 981

When the component first renders, the value of movieData is null.

You should either initialise movieData with an empty array, or conditionally render the content based on whether movieData is truthy (not null).

Upvotes: 1

Kevin Shuguli
Kevin Shuguli

Reputation: 1749

You initialized the movieData as null. So that error occur. Please initialized that movie Data as empty array.

const [movieData, setmovieData] = useState([]);

Upvotes: 2

Related Questions