ReactHustle

How to Add, Update and Remove an Item from Array in React

Jasser Mark Arioste

Jasser Mark Arioste

How to Add, Update and Remove an Item from Array in React

Hello, hustler! In this tutorial, you'll learn how to add, insert, update, and remove items from an array using the useState hook in React. 

How React Compares Objects #

If you're a beginner in React, it might be a bit confusing to know why your array is not updating when you use the useState hook.

First, we have to understand how React compares objects or values to know when something has changed. React compares objects using the strict equality operator (===) in javascript. Meaning,

Consider the following code:


// this will create a reference to arr1 in memory
const arr1 = [1,2,3,4];
// use arr2 to reference arr1;
const arr2 = arr1;
arr2.push(5);
console.log(arr2 === arr1) //true
1234567

Since both arr1 and arr2 share the same reference in memory, meaning they are the same object. Even if we manipulate arr2, it will still be an "alias" of arr1 in the end. Therefore, if you manipulate the same array, it won't update the state in react.

For example:

import { useState } from "react";

export default function Home() {
  const [array, setArray] = useState([1, 2, 3, 4]);
  const addItem = () => {
    const nextVal = array.length + 1;
    array.push(nextVal);
    setArray(array);
  };
  return (
    <div>
      <p>{array.join(",")}</p>
      <button onClick={addItem}>Add item</button>
    </div>
  );
}
12345678910111213141516

In the above code, we try to update the array using array.push but since the object is still the same exact object in memory, React won't rerender the component.

How to Rerender the Component #

To rerender the component, we have to create a new array that has the same exact elements as our previous array. We can do this by using the spread operator, Array.prototype.concat() method, or Array.prototype.slice(), method. The spread operator is usually the most popular one.

Let's update our example:

import { useState } from "react";

export default function Home() {
  const [array, setArray] = useState([1, 2, 3, 4]);
  const addItem = () => {
    const nextVal = array.length + 1;
    const arrayCopy = [...array]; //create a copy of the array
    arrayCopy.push(nextVal);
    setArray(arrayCopy); // update the state using the copy
  };
  return (
    <div>
      <p>{array.join(",")}</p>
      <button onClick={addItem}>Add item</button>
    </div>
  );
}
1234567891011121314151617

Here, we use the spread operator to create a copy of the array and then we use push to update the contents. A more compact code would be to do the following.

 //...
  const addItem = () => {
    const nextVal = array.length + 1;
    // create a copy and add the nextVal as the last element of the array.
    const arrayCopy = [...array, nextVal];
    setArray(arrayCopy);
  };
//...
12345678

This is an extremely important point when trying to update objects or arrays in React. As long as you create a copy, you can re-render the component. Now that we know the basics, we can easily add, insert, update, or remove an item from an array in React.

Adding an Item to an Array #

Adding an item to an array is pretty much the same as our previous example. You can add an item at the end or r at the start of an array.

import { useState } from "react";

export default function Home() {
  const [array, setArray] = useState([1, 2, 3, 4]);
  const addItem = () => {
    const nextVal = array.length + 1;
    // add item at the end
    const arrayCopy = [...array, nextVal];

    // add item at the start
    // const arrayCopy = [nextVal, ...array];
    setArray(arrayCopy);
  };
  return (
    <div>
      <p>{array.join(",")}</p>
      <button onClick={addItem}>Add item</button>
    </div>
  );
}
1234567891011121314151617181920

Inserting an Item into an Array #

To insert an item into an array, first, we create a copy of the array using the spread operator and use the splice method. For example:

import React, { useState } from "react";

type Todo = {
  id: number;
  title: string;
  completed?: boolean;
};

const InsertItemExample = () => {
  const [todos, setTodos] = useState<Todo[]>([
    {
      id: 1,
      title: "Todo1",
      completed: true,
    },
    {
      id: 2,
      title: "Todo2",
    },
  ]);

  const insertAfter = (id: number, todo: Todo) => {
    const array = [...todos]; // first, create a copy.
    // find the index of the id
    const index = todos.findIndex((todo) => todo.id === id);

    // use array.splice to insert it at the next index
    array.splice(index + 1, 0, todo);
    // update the state
    setTodos(array);
  };
  return (
    <div className="p-10">
      {todos.map((todo, i) => {
        return (
          <p key={todo.id} className="p-2">
            {i}.) {todo.title} - {todo.completed ? "Completed" : ""}
          </p>
        );
      })}
      <button
        className="p-2 bg-indigo-500 text-white"
        onClick={() => {
          insertAfter(1, {
            title: "Task 2",
            id: todos.length + 1,
            completed: false,
          });
        }}
      >
        Insert Todo
      </button>
    </div>
  );
};

export default InsertItemExample;
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657

Here's the output:

Inserting an item to an array in React - Example

Updating an Item inside an Array #

To update an item inside an array, we can use Array.prototype.map since this also returns a new array. Here's an example:

import React, { useState } from "react";

type Todo = {
  id: number;
  title: string;
  completed?: boolean;
};

const UpdateItemExample = () => {
  const [todos, setTodos] = useState<Todo[]>([
    {
      id: 1,
      title: "Todo1",
      completed: true,
    },
    {
      id: 2,
      title: "Todo2",
    },
  ]);

  const updateTodo = (updatedTodo: Todo) => {
    // map over the todos
    const updatedArray = todos.map((todo) => {
      // return the updated todo when we find the same id
      if (updatedTodo.id === todo.id) {
        return updatedTodo;
      }

      return todo;
    });

    setTodos(updatedArray);
  };

  return (
    <div className="p-10">
      {todos.map((todo, i) => {
        return (
          <p key={todo.id} className="p-2">
            {i}.) {todo.title} - {todo.completed ? "Completed" : ""}
          </p>
        );
      })}

      <button
        className="p-2 bg-indigo-500 text-white"
        onClick={() => {
          updateTodo({
            id: 2,
            title: "Updated Todo 3",
            completed: true,
          });
        }}
      >
        Update Todo
      </button>
    </div>
  );
};

export default UpdateItemExample;
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162

Here, once the button is clicked, we update the todo with the id:2 with the updated title and completed properties.

Here's the output:

React Update an Item from an Array

Removing an Item from an Array #

To remove an item from an array in React, the best way is still to use Array.prototype.filter in my opinion. This is because it does two things, it returns a new array while filtering the item we want to remove.

Here's an example:

import React, { useState } from "react";

type Todo = {
  id: number;
  title: string;
  completed?: boolean;
};

const RemoveItemExample = () => {
  const [todos, setTodos] = useState<Todo[]>([
    {
      id: 1,
      title: "Todo1",
      completed: true,
    },
    {
      id: 2,
      title: "Todo2",
    },
  ]);

  const removeTodo = (idToRemove: number) => {
    // filter only the todos that doesn't have the id we want to remove
    const updatedArray = todos.filter((todo) => {
      return todo.id !== idToRemove;
    });

    setTodos(updatedArray);
  };

  return (
    <div className="p-10">
      {todos.map((todo, i) => {
        return (
          <div key={todo.id} className="flex gap-2 items-center">
            <p className="p-2">
              {i}.) {todo.title} - {todo.completed ? "Completed" : ""}
            </p>
            <button
              className="bg-red-300 p-2"
              onClick={() => removeTodo(todo.id)}
            >
              (x)
            </button>
          </div>
        );
      })}
    </div>
  );
};

export default RemoveItemExample;
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152

Here's the output:

React remove the item from an array example

That's basically it!

Conclusion #

To update arrays in React, remember that first, we have to create a copy before calling setState. If the object is the same, it won't re-render the component. There are multiple ways to create new arrays in Javascript such as the spread operator, and array methods such as but not limited to filter(), map(), slice(), and concat().

If you like this tutorial, please leave a like or share this article. For future tutorials like this, please subscribe to our newsletter or follow me on GitHub.

Resources #

Credits: Image by Elias Obernosterer from Pixabay

Share this post!

Related Posts