Typeerror Cannot Read Property 'data' of Undefined React
This is one of the more common errors you will run into when starting out with React:
Cannot read belongings 'map' of undefined
In this post, nosotros'll acquire how to fix information technology.
Why It's Happening
The variable you lot are trying to map
over is undefined
. Information technology will probably eventually be an array, only due to the asynchronous nature of React, you are experiencing at least i render when the variable is undefined
.
Let's have this example code. In it, we fetch some data from an API and set land with that data.
function MyComponent ( ) { const [data, setData] = useState ( ) ; useEffect ( ( ) => { fetch ( '/api/data' ) . then ( ( res ) => res. json ( ) ) . so ( ( data ) => { setData (data) ; } ) . grab ( ( err ) => { console. log (err) ; } ) ; } , [ ] ) ; return ( <ul > {information. map ( ( item ) => ( <li fundamental = {item.id} > {item.proper noun} </li > ) ) } </ul > ) ; }
This lawmaking might seem fine, but our data fetching takes some time and React does not expect for the data fetching (or any async action) to happen earlier it showtime renders your JSX. That means, while the data is beingness fetched, React is trying to run information.map(...)
.
Since nosotros provided no initial value for information
in our useState
claw, data
is undefined
. As nosotros know from the mistake message, it'southward problematic to try to call map
on undefined
!
Fix Option 1: Default the Variable to an Empty Array
This first quick set up might exist enough for your use instance: just default your stateful variable to an array while y'all're waiting for your data to fetch. For instance:
function MyComponent ( ) { // Empty array in useState! 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 > ) ; }
The reason this works is that, while your data fetching is happening, React volition phone call the map
method on an empty data
array. This is fine—nothing will be rendered and there will be no errors. Once the data loads from the API phone call, our information
state will be set and our list will correctly render.
Fix Option 2: Showing a Loading Indicator
While the previous fix is simple, it might not be the best user experience to brandish nothing until the data loads. Instead, we might choose to brandish a loading indicator. In that location are a few ways we can do this, but one of the simpler ways is to just add together some other stateful variable called loading
.
function MyComponent ( ) { const [information, setData] = useState ( [ ] ) ; const [loading, setLoading] = useState ( false ) ; useEffect ( ( ) => { setLoading ( truthful ) ; fetch ( '/api/data' ) . and then ( ( res ) => res. json ( ) ) . so ( ( data ) => { setData (data) ; } ) . catch ( ( err ) => { panel. log (err) ; } ) . finally ( ( ) => { setLoading ( fake ) ; } ) ; } , [ ] ) ; if (loading) { render <p > Data is loading... </p > ; } return ( <ul > {data. map ( ( item ) => ( <li fundamental = {item.id} > {item.name} </li > ) ) } </ul > ) ; }
This is pretty uncomplicated and effective! When our data starts to fetch, we set loading
to true
. When it's done fetching, nosotros set 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…
Nosotros should probably handle the situation in which our fetch fails. Additionally, nosotros can prove the user an error message if our data variable is not an assortment. This latter point is important in making sure that we never effort to access the map
property on a non-array since it just won't work.
office MyComponent ( ) { const [data, setData] = useState ( [ ] ) ; const [loading, setLoading] = useState ( false ) ; const [fault, setError] = useState ( ) ; useEffect ( ( ) => { setLoading ( truthful ) ; fetch ( '/api/data' ) . and so ( ( res ) => res. json ( ) ) . then ( ( data ) => { setData (data) ; } ) . take hold of ( ( err ) => { setError (err) ; } ) . finally ( ( ) => { setLoading ( false ) ; } ) ; } , [ ] ) ; if (loading) { render <p > Information is loading... </p > ; } if (error || !Assortment. isArray (data) ) { return <p > There was an error loading your information! </p > ; } render ( <ul > {information. map ( ( item ) => ( <li key = {item.id} > {item.name} </li > ) ) } </ul > ) ; }
And at present we have a pretty prophylactic way of handling our async operation without getting the dreaded "cannot read property 'map' of undefined" error!
If y'all'd similar to support this web log by buying me a java I'd actually appreciate it!
Source: https://typeofnan.dev/fix-cannot-read-property-map-of-undefined-error-in-react/
0 Response to "Typeerror Cannot Read Property 'data' of Undefined React"
Post a Comment