Updating react nested state properties
Tags: react, javascript
Published: 2019-01-06 17:49:47

---
title: Updating react nested state properties
published: true
description: React setState doesn't take care of nested properties out of the box, we will take a look at how to fix this.
tags: reactjs, javascript, react
---

![alt-text](https://thepracticaldev.s3.amazonaws.com/i/pd50euhxmawva1ns3y0a.png "")

Working with react inevitable requires you to manage the state of your application at some point, bearest minimum the state of a component you're currently working with.

Recently, I was working on a side project, and I felt like trying something different from the regular ```this.state = { email: '', password: '' };``` 

I was trying to login a user with email and password credential, so I felt like wrapping that up into a user object for human readability or better still no reason sake :).

I did this
```javascript
this.state = {
  user: {
    email: '',
    password: ''
  }
};
```

Then i noticed my form fields were not taking in the inputs, more like its on readOnly mode.

After googling, it occured to me that the state wasn't updating using the regular 
```javascript
 onChange(e) {
   const { name, value } = e.target;
   this.setState({ [name]: value });
```
Why because the properties (email and password) are nested under the user state property. At first, I was like that shouldn't be much of a problem, calling `user.email, user.password` should do the trick right? You guessed right, it didn't and there i was thinking straight i just wanted things to work so I can move on wiht my code.

### The Solution
 
#### Quick answer:

```javascript
onChange(e) { 
  const { user } = { ...this.state };
  const currentState = user;
  const { name, value } = e.target;
  currentState[name] = value;

  this.setState({ user: currentState });
}
```

#### Long Version:

react's setState doesn't take care of nested properties, in this case `email` and `password`. So the only way to make changes is to access the parent state object `user` whenever a new change occurs to either `email` or `password`.

What this means is that everytime you type a new character on any of the field, the user state gets to be re-created. This is not optimal if your user object has lots of fields say like a bulky registration form dealing with over 10 fields is not considered ideal.

The above code uses some es6 features, such as the spread operator & Destructuring.

It's a general bad practise to mutate (add/remove elements of the state directly) state in react. states should be recreated if it must change.

The line `const { user } = { ...this.state }` does just that using the spread operator(...) to get the current state. Assigned the value returned to currentState variable `const currentState = user;`, destructure the emmitted events `const { name, value } = e.target;` coming from the input fields to get the name and thier value. Update the currentState with the value of the input `currentState[name] = value;` where name is the property of the user state object `email` and `password`.

Finally, we transpose the `user` with the `currentState` whenever an update has been successfully made `this.setState({ user: currentState });`.

### My recommendation

Some people will argue about using nested properties because React is not oriented to work with nested state. Maybe this is correct or not but here's what I think;

I would suggest you avoid using nested state, if you must then endeavor to make it as light as possible because the downside is every tiny piece of change will recreate the parent object, which is not good for performance.