Typeerror: Cannot Read Property 'getinstance' of Undefined'

React - Cannot read property 'map' of undefined

March 12, 2020 - 5 min read

If you are a react developer, there is a good chance that you faced this error couple of times:

TypeError: Cannot read belongings 'map' of undefined

TL;DR - If you are not in the mode for reading or y'all just want the bottom line, then hither it is

The problem

In order to empathise what are the possible solutions, lets first understand what is the exact issue here.

Consider this code block:

                          // Just a information fetching function              const              fetchURL              =              "https://jsonplaceholder.typicode.com/todos/"              ;              const              getItems              =              (              )              =>              fetch              (fetchURL)              .              then              (              res              =>              res.              json              (              )              )              ;              function              App              (              )              {              const              [items,              setItems]              =              useState              (              )              ;              useEffect              (              (              )              =>              {              getItems              (              )              .              and then              (              data              =>              setItems              (data)              )              ;              }              ,              [              ]              )              ;              return              (                                                <div                >                                                        {items.              map              (              item              =>              (                                                <div                central                                  =                  {detail.id}                                >                            {item.title}                                                </div                >                            )              )              }                                                                            </div                >                            )              ;              }                      

We have a component that manage a land of items, it also have an effect which inside it nosotros run an asynchronous operation - getItems, which will return us the information we need from the server, then we call setItems with the received data as items. This component also renders the items - information technology iterate over it with .map and returning a react element for each detail.

But nosotros wont see anything on the screen, well except the error:

TypeError: Cannot read belongings 'map' of undefined

What'southward going on here?

We do accept an items variable:

                          const              [items,              setItems]              =              useState              (              )              ;                      

And we did populate information technology with our data returned from the server:

                          useEffect              (              (              )              =>              {                              getItems                (                )                .                and then                (                information                =>                setItems                (data)                )                ;                            }              ,              [              ]              )              ;                      

Well lets examine how the react catamenia looks similar in our instance:

  1. React renders (invoking) our component.
  2. React "run into" the useState telephone call and return us [undefined, fn].
  3. React evaluate our render statement, when information technology hits the items.map(...) line its actually running undefined.map(...) which is manifestly an error in JavaScript.

What about our useEffect call though?

React will run all effects after the render is committed to the screen, which means we can't avoid a first render without our information.

Possible solutions

#one Initial value

One possible solution is to give your variable a default initial value, with useState it would expect like that:

                          const              [items,              setItems]              =              useState              (              [              ]              )              ;                      

This ways that when react runs our useState([]) call, it will return united states of america with

Which means that in the first render of our component, react volition "run into" our items as an empty array, and then instead of running undefined.map(...) like before, information technology will run [].map(...).

#2 Conditional rendering

Another possible solution is to conditionally render the items, meaning if we accept the items then render them, else don't render (or render something else).

When working with JSX we can't just throw some if else statements inside our tree:

                          // ⚠️ wont work!!              consign              default              function              App              (              )              {              // ....              return              (                                                <div                >                                                                      {                              if                (items)                {                                            items.                map                (                detail                =>                (                                                                                  <div                  key                                      =                    {item.id}                                    >                                {item.title}                                                      </div                  >                                                            )                )                                            }                            }                                                                                          </div                >                            )              ;              }                      

But instead we can create a variable outside our tree and populate information technology conditionally:

Note that nosotros removed the initial array for items.

                          office              App              (              )              {              const              [items,              setItems]              =              useState              (              )              ;              useEffect              (              (              )              =>              {              getItems              (              )              .              and then              (              data              =>              setItems              (data)              )              ;              }              ,              [              ]              )              ;                              let                itemsToRender;                                            if                (items)                {                                            itemsToRender                =                items.                map                (                item                =>                {                                            return                                                      <div                  cardinal                                      =                    {item.id}                                    >                                {item.title}                                                      </div                  >                                ;                                            }                )                ;                                            }                                            return                                                      <div                  >                                {itemsToRender}                                                      </div                  >                                ;                            }                      

The undefined or null values are ignored within the context of JSX and so its safety to pass it on for the outset render.

We could besides use an else argument if we want to render something else like a spinner or some text:

                          function              App              (              )              {              const              [items,              setItems]              =              useState              (              )              ;              useEffect              (              (              )              =>              {              getItems              (              )              .              and then              (              data              =>              setItems              (data)              )              ;              }              ,              [              ]              )              ;              let              itemsToRender;              if              (items)              {              itemsToRender              =              items.              map              (              particular              =>              {              render                                                <div                key                                  =                  {item.id}                                >                            {detail.championship}                                                </div                >                            ;              }              )              ;                              }                else                {                                            itemsToRender                =                "Loading..."                ;                                            }                            return                                                <div                >                            {itemsToRender}                                                </div                >                            ;              }                      

#ii.5 Inline conditional rendering

Another option to conditionally render something in react, is to use the && logical operator:

                          function              App              (              )              {              const              [items,              setItems]              =              useState              (              )              ;              useEffect              (              (              )              =>              {              getItems              (              )              .              so              (              data              =>              setItems              (data)              )              ;              }              ,              [              ]              )              ;              return              (                                                <div                >                                                                                          {items                &&                items.                map                (                item                =>                {                                            return                                                      <div                  key                                      =                    {item.id}                                    >                                {item.championship}                                                      </div                  >                                ;                                            }                )                }                                                                                                          </div                >                            )              ;              }                      

Why information technology works? The react docs explains information technology well:

It works because in JavaScript, true && expression always evaluates to expression, and false && expression always evaluates to false. Therefore, if the status is truthful, the element right after && will announced in the output. If it is false, React will ignore and skip it.

We can also use the conditional operator condition ? true : false if we want to render the Loading... text:

                          function              App              (              )              {              const              [items,              setItems]              =              useState              (              )              ;              useEffect              (              (              )              =>              {              getItems              (              )              .              then              (              data              =>              setItems              (information)              )              ;              }              ,              [              ]              )              ;              render              (                                                <div                >                                                                                          {items                              ?                items.                map                (                particular                =>                {                                            render                                                      <div                  key                                      =                    {item.id}                                    >                                {item.title}                                                      </div                  >                                ;                                            }                )                                            :                "Loading..."                }                                                                                                          </div                >                            )              ;              }                      

We can likewise mix both solutions, i.e: initial value with conditional rendering:

                          function              App              (              )              {                              const                [items,                setItems]                =                useState                (                [                ]                )                ;                            useEffect              (              (              )              =>              {              getItems              (              )              .              and so              (              information              =>              setItems              (data)              )              ;              }              ,              [              ]              )              ;              render              (                                                <div                >                                                                                          {items                &&                items.length                >                0                                            ?                items.                map                (                particular                =>                {                                            return                                                      <div                  key                                      =                    {detail.id}                                    >                                {item.title}                                                      </div                  >                                ;                                            }                )                                            :                "Loading..."                }                                                                                                          </div                >                            )              ;              }                      

Though proceed in mind, whenever weather become too complex, it might be a signal for us to excerpt that logic to a component:

                                          part                List                (                                  {                  items,                  fallback                  }                                )                {                                            if                (                !items                ||                items.length                ===                0                )                {                                            return                fallback;                                            }                else                {                                            return                items.                map                (                item                =>                {                                            return                                                      <div                  central                                      =                    {particular.id}                                    >                                {item.championship}                                                      </div                  >                                ;                                            }                )                ;                                            }                                            }                            part              App              (              )              {              const              [items,              setItems]              =              useState              (              [              ]              )              ;              useEffect              (              (              )              =>              {              getItems              (              )              .              then              (              information              =>              setItems              (data)              )              ;              }              ,              [              ]              )              ;              render              (                                                <div                >                                                                                                                                <                    List                                    items                                      =                    {items}                                    fallback                                      =                    {                    "Loading..."                    }                                    />                                                                                                                          </div                >                            )              ;              }                      

Wrapping up

When we get such an error, we are probably getting the value in an asynchronous way. Nosotros should provide an initial value for our variable or conditionally return it or both. If our condition go too complex, it might be a good time to extract the logic to a component.

Hope y'all plant this article helpful, if you have a different approach or any suggestions i would love to hear about them, you can tweet or DM me @sag1v. 🤓

highsmithapereens.blogspot.com

Source: https://www.debuggr.io/react-map-of-undefined/

0 Response to "Typeerror: Cannot Read Property 'getinstance' of Undefined'"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel