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!

Nick Scialli

perezthersid.blogspot.com

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

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel