Typeerror: Cannot Read Property 'name' of Undefined React Object Props
This is one of the more mutual errors you will run into when starting out with React:
Cannot read belongings 'map' of undefined
In this post, nosotros'll learn how to fix it.
Why It's Happening
The variable you are trying to map
over is undefined
. It will probably eventually exist an array, merely due to the asynchronous nature of React, yous are experiencing at least one render when the variable is undefined
.
Let'southward take this instance code. In information technology, we fetch some data from an API and set state with that data.
function MyComponent ( ) { const [data, setData] = useState ( ) ; useEffect ( ( ) => { fetch ( '/api/data' ) . then ( ( res ) => res. json ( ) ) . then ( ( data ) => { setData (data) ; } ) . catch ( ( err ) => { console. log (err) ; } ) ; } , [ ] ) ; return ( <ul > {data. map ( ( item ) => ( <li key = {particular.id} > {item.name} </li > ) ) } </ul > ) ; }
This code might seem fine, but our data fetching takes some time and React does non await for the data fetching (or any async activity) to happen before it first renders your JSX. That ways, while the data is beingness fetched, React is trying to run data.map(...)
.
Since we provided no initial value for data
in our useState
hook, information
is undefined
. As nosotros know from the error message, it's problematic to endeavor to call map
on undefined
!
Set up Choice i: Default the Variable to an Empty Array
This first quick prepare might exist enough for your use example: just default your stateful variable to an array while you lot're waiting for your data to fetch. For instance:
part MyComponent ( ) { // Empty array in useState! const [data, setData] = useState ( [ ] ) ; useEffect ( ( ) => { fetch ( '/api/data' ) . then ( ( res ) => res. json ( ) ) . so ( ( data ) => { setData (data) ; } ) . catch ( ( err ) => { panel. log (err) ; } ) ; } , [ ] ) ; return ( <ul > {information. map ( ( item ) => ( <li central = {particular.id} > {item.name} </li > ) ) } </ul > ) ; }
The reason this works is that, while your data fetching is happening, React volition call the map
method on an empty data
assortment. This is fine—nothing will be rendered and in that location will be no errors. Once the data loads from the API telephone call, our information
state will be set and our list will correctly render.
Set Choice 2: Showing a Loading Indicator
While the previous prepare is simple, information technology might not exist the best user experience to brandish nothing until the data loads. Instead, nosotros might cull to display a loading indicator. There are a few ways nosotros tin do this, just i of the simpler ways is to merely add another stateful variable called loading
.
function MyComponent ( ) { const [information, setData] = useState ( [ ] ) ; const [loading, setLoading] = useState ( false ) ; useEffect ( ( ) => { setLoading ( true ) ; fetch ( '/api/data' ) . and so ( ( res ) => res. json ( ) ) . then ( ( data ) => { setData (data) ; } ) . catch ( ( err ) => { console. log (err) ; } ) . finally ( ( ) => { setLoading ( faux ) ; } ) ; } , [ ] ) ; if (loading) { render <p > Data is loading... </p > ; } render ( <ul > {data. map ( ( item ) => ( <li key = {item.id} > {item.name} </li > ) ) } </ul > ) ; }
This is pretty simple and effective! When our data starts to fetch, we gear up loading
to true
. When it's done fetching, we set up loading
to false
. Note that we utilise the finally
method on our Promise since that will run regardless of whether the fetch succeeds or fails.
Speaking of Fetch Failures…
We should probably handle the situation in which our fetch fails. Additionally, we can show the user an error message if our data variable is not an array. This latter point is important in making sure that we never attempt to access the map
property on a non-assortment since it simply won't piece of work.
role MyComponent ( ) { const [data, setData] = useState ( [ ] ) ; const [loading, setLoading] = useState ( false ) ; const [error, setError] = useState ( ) ; useEffect ( ( ) => { setLoading ( truthful ) ; fetch ( '/api/data' ) . then ( ( res ) => res. json ( ) ) . then ( ( data ) => { setData (data) ; } ) . catch ( ( err ) => { setError (err) ; } ) . finally ( ( ) => { setLoading ( simulated ) ; } ) ; } , [ ] ) ; if (loading) { return <p > Data is loading... </p > ; } if (error || !Array. isArray (information) ) { return <p > In that location was an error loading your information! </p > ; } return ( <ul > {information. map ( ( particular ) => ( <li key = {detail.id} > {item.name} </li > ) ) } </ul > ) ; }
And now we have a pretty safe way of handling our async operation without getting the dreaded "cannot read property 'map' of undefined" error!
If yous'd similar to back up this web log by ownership me a coffee I'd really appreciate it!
![Nick Scialli](/static/f954ab40cc2cf0a4e34ac51f98889561/e07e1/light.jpg)
Source: https://typeofnan.dev/fix-cannot-read-property-map-of-undefined-error-in-react/
0 Response to "Typeerror: Cannot Read Property 'name' of Undefined React Object Props"
Post a Comment