user

Joseph Morgan

10 Jun 2021

[Solved] Cannot read property 'map' of undefined in React JS useState and useEffect function

React js

Hello everybody,
There is an error in my React js website which I am learning on it, this problem is in map() function, it cannot get the data correctly from the state when the value of the State is coming from useEffect Hook so the current code is like this 

import React, { useState, useEffect } from 'react';

const Posts = ({data}) => {
 const [posts, setPosts] = useState();

 useEffect(() => {
 setPosts(data.posts);
 }, [setPosts, data]);

 return (
 posts.map((post) => {
 return(
 <p key={post.title}>{post.title}<br/></p>
 );
 })
 );
}
export default Posts;

This doesn't work but when I try to add the data inside the state directly like 

import React, { useState, useEffect } from 'react';

const Posts = ({data}) => {
 const [posts, setPosts] = useState([
 {title: 'test', name: 'Hello world', date: '6/10/2021'},
 {title: 'test2', name: 'world', date: '6/10/2021'}
 ]);

 useEffect(() => {
 setPosts(data.posts);
 }, [setPosts, data]);

 return (
 posts.map((post) => {
 return(
 <p key={post.title}>{post.title}<br/></p>
 );
 })
 );
}
export default Posts;

It works fine without any problem, is this error are in the props? when I send the data to the child component? 

I will be pleased if I find any expert to figure this out 

Comments

Mohamed Atef

10 Jun 2021

Best Answer

best answer
githubgithubgithub

Hi Joseph,

This is admin Mohamed Atef, from what I see, I am going to help you to pass this error,
First, this happens because on the first run of the page the browser returns this error because the ‘posts’ constraint, has no value on the first run of the browser because of the “asynchronous” which React js uses in the useState so all we gonna is just adding a empty array inside the ‘posts’ constraint so it can be like a placeholder until the browser get the correct value 
like 

import React, { useState, useEffect } from 'react';

const Posts = ({data}) => {
 // we just gonna add [] inside teh useState function
 const [posts, setPosts] = useState([]);

 useEffect(() => {
 setPosts(data.posts);
 }, [setPosts, data]);
 
 return (
 posts.map((post) => {
 return(
 <p key={post.title}>{post.title}<br/></p>
 );
 })
 );
}
export default Posts;

or We can prevent the return (if the ‘posts’ constraint has no value) by adding an if statement above the current return (contain return null in case of there is no value for the ‘posts’ constraint) to be like this 

import React, { useState, useEffect } from 'react';

const Posts = ({data}) => {
 const [posts, setPosts] = useState();

 useEffect(() => {
 setPosts(data.posts);
 }, [setPosts, data]);
 
 // Add this condition below
 if(!posts){
 return null;
 }
 return (
 posts.map((post) => {
 return(
 <p key={post.title}>{post.title}<br/></p>
 );
 })
 );
}
export default Posts;

Thanks hope this make you realize the idea of asynchronous & solve your error 

Replies

Joseph Morgan

10 Jun 2021

Ohh, Thank you so much you really saved my life, I have been thinking about it for 3 hours

© 2024 Copyrights reserved for web-brackets.com