My most frequent React errors and how you fix them
Tags: react, javascript, webdev, programming
Published: 2021-04-15 17:29:36

When using the popular JavaScript library **React** there are some errors/problems that seem to pop up time and time again. They can be easily avoided in most situations and I would like to share them with you so you can spend less time debugging and more time writing code.

So let's not waste any time and take a look at our problems and how we can solve them 👏.

## Content

1. Forgetting to add keys with a list of elements
2. Not returning a list correctly
3. Not cleaning up certain `useEffect` side-effects
4. Not wrapping adjacent JSX elements

## 1) Forgetting to add keys with a list of elements

In React we often find ourselves with lists of data that we want to map into elements or components. This is often done using the `Array.prototype.map` function to pass data from each index of the array to the element or component through props.

When we do this without adding a `key` prop React will complain that each element is missing a `key`. Essentially it is just a special attribute to which we pass a string. It should be a unique string which will distinguish it from its siblings that we are also mapping.

React says:

>Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity

### Example Problem

Let's map some data before adding keys to our elements to see the problem in action. Here we will have a simple component that deconstructs `foods` from the prop object. `foods` is just an array of objects and it looks like this 👇

![Our example data set](https://cdn.hashnode.com/res/hashnode/image/upload/v1616319710734/6rUdcew2_.jpeg)

and our component 👇

![mapped elements without key prop](https://cdn.hashnode.com/res/hashnode/image/upload/v1616097340131/FXRGm0Ja8.jpeg)

and finally the warning from React 👇.

![missing key warning](https://cdn.hashnode.com/res/hashnode/image/upload/v1616097229831/VhLrfT86h.jpeg)

### Solution

To fix this all we have to do is pass a unique key to the element we are returning. Often the data we are mapping comes from a fetch request and usually includes an id. Fortunately we have and `id` property we can use from our set of data. Let's add our `key` property.

![After adding our key prop](https://cdn.hashnode.com/res/hashnode/image/upload/v1616320768295/os2fTkk5n.jpeg)

If we didn't have a unique id we would need to have an alternative solution. Often people use the index of the array as the `key` but this is not recommended for any set of data where positions in the list  may change. It can negatively affect the state of the component. See here for more information [Reactjs - Reconciliation](https://reactjs.org/docs/reconciliation.html#recursing-on-children).

Instead we could create our key by combining the `name` property with the current date/time using the JavaScript `Date` object.

## 2) Not returning a list correctly

***To return or not to return***

In React as we have already seen we are often iterating over some data . Perhaps we are filtering a data set down to a specific sub-set or mapping to the DOM. Whatever it is there are a few pitfalls we need to watch out for when it comes to returning our data otherwise we might be left scratching our heads.

### Example Problem

A frustrating example can be seen when we map a data set to some elements or components. We expect to see the or elements on screen with the data we map into them. However we see nothing.

No error, no warning no data 🤨. In this situation it is likely that you're not returning your result correctly.

For our example we will be mapping our array of foods to some elements so we can show it to the user. It should look like this:

![Correct return demonstration](https://cdn.hashnode.com/res/hashnode/image/upload/v1616091546766/lvvPV1DEv.jpeg)

Instead our data will appear to be missing 👇.

![Incorrect return demonstration](https://cdn.hashnode.com/res/hashnode/image/upload/v1616091661813/ixeEBjbHO.jpeg)

Let me show you some examples where we won't see the output that we were expecting. We are passing our array to our component and destructuring it from the prop object the same as before.

Can you spot the problem below.

![Example of not returning correclty](https://cdn.hashnode.com/res/hashnode/image/upload/v1616322199327/hc-IGwpvu.jpeg)

Correct! Here we are not returning anything either implicitly or explicitly using the `return` keyword.

Let's take a look at another  👇.

![Second example of not returning correctly](https://cdn.hashnode.com/res/hashnode/image/upload/v1616322293046/tFRUeU4F9.jpeg)

This time we include the `return` keyword but what we are actually doing here is returning `undefined`. The code below the return statement never gets read.

There are other examples you might run into but let's take a look at the different solutions we can use.

### Solution

Let's start with the explicit returns. If we move our `article` element in line with the return statement all is well. 

See below 👇

![Example of correct explicit return](https://cdn.hashnode.com/res/hashnode/image/upload/v1616322563273/b5DhsigYN.jpeg)

We could also wrap the return elements with parenthesis like this:

![Example of correct explicit return](https://cdn.hashnode.com/res/hashnode/image/upload/v1616322655801/uSlQpxqxJ.jpeg)

Another option is to return the result implicitly which means we can forget the `return` statement and the function body curly braces. Check it out 👇.

![Example of correct implicit return](https://cdn.hashnode.com/res/hashnode/image/upload/v1616322842007/nwRlqVGQN.jpeg)

or inline like this 👇.

![Example of correct implicit return](https://cdn.hashnode.com/res/hashnode/image/upload/v1616322878711/54EU5aA4P.jpeg)

The choice is up to you as long as you are aware of the possible pitfalls you encounter. If the data appears to be missing make sure you check your map function carefully and make sure you are actually returning correctly.

## 3) Not cleaning up certain `useEffect` side-effects

The `useEffect` hook allows us to perform side-effects inside functional components. Certain side-effects that we perform in this hook require cleanup. This means that when the component unmounts we can run a special function. Sometimes this is necessary otherwise we might see an error warning us of memory leaks in our apps.

Consider a `useEffect` that performs some kind of asynchronous api call before setting some component state to the response. If the response is slow and the component unmounts before we receive a response then we might be trying to update the state of a component that is not mounted.

### Example Problem

Let's take a look at two different situations where we might add some cleanup to our `useEffect`.

The first is a situation is where we have an asynchronous fetch request inside our `useEffect` hook. The user of the application navigates to a different page before we receive the response from the fetch call. This is our component before we add a cleanup function to the`useEffect` hook.

![React useEffect before cleanup](https://cdn.hashnode.com/res/hashnode/image/upload/v1616093842029/q9hZoLWhz.jpeg)

Here we are fetching some data after the component mounts and then using the result to set the components state. Finally we map the state to the DOM. Relatively straight forward 👍.

The second situation is where we add some `eventListeners` to some DOM elements. If the component unmounts we are going to want to remove these listeners.

Check it out before we clean it up 👇

![Before adding our cleanup function to useEffect](https://cdn.hashnode.com/res/hashnode/image/upload/v1616148044886/8QpSp5s1C.jpeg)

The logic inside our `useEffect` is irrelevant for this simple example. All that matters is that we are adding an event listener and that will need to be cleaned up.

### Solution

We begin by adding a cleanup function to our `useEffect` like this:

![useEffect cleanup function](https://cdn.hashnode.com/res/hashnode/image/upload/v1616094306440/CsabPIn7C.jpeg)

It is simply a function that we add to the bottom of our `useEffect` hook where we add our cleanup logic.

Now to cleanup our fetch request we can use the DOM api `AbortController` which is available in JavaScript. It allows us to abort web requests which we will use to abort out of the fetch request whenever the component unmounts. Let's see it in action 👇.

![React useEffect fetch cleanup function](https://cdn.hashnode.com/res/hashnode/image/upload/v1616094823496/Bj_AASqiD.jpeg)

First we create a controller by using the constructor with `new AbortController()` and then we pass its property signal to the fetch request. This association of controller signal to the request allows us to abort the request by calling `abort()` inside the cleanup function.

Now we are ensuring that we don't have any requests coming back to a component that is not mounted.

The cleanup function for our `eventListener` example is simple which you might have already guessed. All we need to do is remove any listeners we create using `removeEventListener` in our cleanup function. Let's see it in action 👇.

![React useEffect listener cleanup example](https://cdn.hashnode.com/res/hashnode/image/upload/v1616095810890/1r2ISzE03.jpeg)

Hopefully now like me you won't forget to clean up your effects 😉.

## 4) Not wrapping adjacent JSX elements

This one is simple to debug but I though I would include it because I sometimes forget to do it until React starts shouting at me 😅. 

Adjacent JSX elements must be wrapped with an enclosing tag. There are a few different ways we can do this based on our requirements.

### Example Problem

If we want the wrapper to be part of the DOM for structural purposes then go with some semantic element where possible (`<article>`, `<section>` etc.). I usually wouldn't recommend wrapping elements with a `<div>` although it is fine if you want the wrapper for styling purposes.

Often we do not want the wrapper to part of the DOM because it serves no purpose there. We would only be adding markup only to shut React up. 

Let's see the problem in action.

![Example component not wrapping adjacent JSX](https://cdn.hashnode.com/res/hashnode/image/upload/v1616148632836/OIPeZEhWo.jpeg)

and the error it throws 👇

![Adjacent JSX error](https://cdn.hashnode.com/res/hashnode/image/upload/v1616324446263/8d7lh2I4s.jpeg)

It is likely that your code editor gave you a warning about this before the error pops up which is great.


### Solution

Fortunately React provides us with a solution. We can use `React.Fragment` to wrap our adjacent JSX if we do not require the wrapper to be part of the DOM. Let's say this is the case for the following example.  

First let's use `React.Fragment` before we see how we can simplify it further.

![Wrapping adjacent JSX with React.Fragment](https://cdn.hashnode.com/res/hashnode/image/upload/v1616151255932/oiUWsfKSg.jpeg)

If we don't need any attributes or keys for our fragment we can shorten `React.Fragment` to this `<>` empty tag. Have a look below.

![Wrapping adjacent JSX with React.Fragment shortened syntax](https://cdn.hashnode.com/res/hashnode/image/upload/v1616151408216/ZujqMuMMe.jpeg)

Finally if we are mapping some data to JSX as we have previously seen then we need to add keys to our wrapping element. If all we have is adjacent JSX then we can wrap our elements with `React.Fragment` and add a unique key to the fragment.

![Wrapping our mapped adjacent JSX with React.fragment and a unique key](https://cdn.hashnode.com/res/hashnode/image/upload/v1616152071199/3FGAy87WV.jpeg)

## Conclusion

Thanks for getting this far! I hope you learned something from the article and now we can both make sure we avoid these problems in our future code.

If you enjoyed it feel free to drop a 👍 on the article. It inspires me to continue improving and make more awesome content.

If you would like to connect with me then come an say hi [@Kieran6dev](https://twitter.com/Kieran6dev) as I am always active in communicating with other devs over on Twitter.

Thanks!