How to update an array state in React.Js
Tags: react, reactnative, javascript, typescript
Published: 2021-01-20 21:16:08

Ever tried to update an array in the React and ended up mutating the existing state?
Then you might be wondering why your component didn't update. Well you are not alone i did that too, and turns out a lot of other people face the exact same issue. 

Let's learn the correct way to do it today...

## Let's take an example of a list.

- We will allow addition of a new items to the list.
- Deletion of an item.
- Adding an item at a specific point in an array.

### Addition of an element.

```jsx

// Method 1 -> Use array destructure
const addUser = () => {
  const newUser = {
    id: Date.now(),
    username: `User ${users.length + 1}`
  };
  const newUsers = [...users, newUser];

  setUsers(newUsers);
};

// Method 2 -> Use slice method with combination of push method.
const addUser = () => {
  const newUser = {
    id: Date.now(),
    username: `User ${users.length + 1}`
  };

  const newUsers = users.slice();
  newUsers.push(newUser);

  setUsers(newUsers);
};
```

With method one we are simply using ES6 array destructing and appending an element to it. Where as method 2 goes old school using `slice` and `push` methods.

### Deletion of an element.

```jsx

// Method 1 -> Use array destructure
const removeUser = (index) => () => {
    const newUsers = [...users];
    newUsers.splice(index, 1);

    setUsers(newUsers);
  };

// Method 2 -> Use slice method.
const removeUser = (index) => () => {
    const newUsers = users.slice();
    newUsers.splice(index, 1);

    setUsers(newUsers);
  };

```

With method one we are simply using ES6 array destructing to shallow clone the array and then mutating the new array by deleting the element. With method 2 we are using `slice` to shallow clone the array.

### Addition of an element at a specific index.

```jsx
	
  // Method 1 -> Use array destrcture.
  const addAfter = (index) => () => {
    const newUser = {
      id: Date.now(),
      username: `User ${users.length + 1}`
    };

    const newUsers = [
      ...users.slice(0, index + 1),
      newUser,
      ...users.slice(index + 1)
    ];

    setUsers(newUsers);
  };

	// Method 2 -> Using splice
  const addAfter = (index) => () => {
    const newUser = {
      id: Date.now(),
      username: `User ${users.length + 1}`
    };
    const newUsers = [...users]; 
    newUsers.splice(index + 1, 0, newUser)

    setUsers(newUsers);
  };
```

With method one we are using `slice` , `slice(start, length)` we grab all the elements till the given index. After that we append the new element, lastly using `slice(index + 1)` we are taking the remaining items from the original array and concentrate everything using ES6 array destructing.

Method 2 we are taking advantage of a quirk that comes with array `[splice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)` with splice we can push the elements in array as well using its 3rd argument.  

## Full Code [[https://codesandbox.io/s/objective-rgb-4z4yz?file=/src/App.js](https://codesandbox.io/s/objective-rgb-4z4yz?file=/src/App.js)]

```jsx
import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [users, setUsers] = useState([
    { id: Date.now() + 1, username: "User 1" },
    { id: Date.now() + 2, username: "User 2" }
  ]);

  const addUser = () => {
    const newUser = {
      id: Date.now(),
      username: `User ${users.length + 1}`
    };
    // Method 1 -> Use array destructure
    const newUsers = [...users, newUser];

    // Method 2 -> Use slice method with combination of push method.
    // const newUsers = users.slice();
    // newUsers.push(newUser);

    setUsers(newUsers);
  };

  const removeUser = (index) => () => {
    // Method 1 -> Use array destrcture.
    const newUsers = [...users];
    newUsers.splice(index, 1);

    // Method 2 -> Use slice method.
    // const newUsers = users.slice();
    // newUsers.splice(index, 1);

    setUsers(newUsers);
  };

  const addAfter = (index) => () => {
    const newUser = {
      id: Date.now(),
      username: `User ${users.length + 1}`
    };
    // Method 1 -> Use array destrcture.
    // const newUsers = [
    //   ...users.slice(0, index + 1),
    //   newUser,
    //   ...users.slice(index + 1)
    // ];

    // Method 2 -> Using splice
    const newUsers = [...users]; 
    newUsers.splice(index + 1, 0, newUser)

    setUsers(newUsers);
  };

  return (
    <>
      <button onClick={addUser}>Add User</button>
      {users.map((user, index) => (
        <div className="user" key={user.id}>
          {user.username}
          <button onClick={removeUser(index)}>Remove User</button>
          <button onClick={addAfter(index)}>Add immediate next User</button>
        </div>
      ))}
    </>
  );
}
```