DEV Community

Cover image for Efficiently Managing Dynamic State Arrays in React: Adding and Removing Elements with Ease 📣
Pratik Tamhane
Pratik Tamhane

Posted on

Efficiently Managing Dynamic State Arrays in React: Adding and Removing Elements with Ease 📣

Introduction

In this article, we’ll walk through how to create a "Next" and "Back" button functionality in a React component. The goal is to add elements to an array on the "Next" button click and remove the last element on the "Back" button click, while managing state efficiently. This approach is useful in scenarios where you need to navigate through steps or stages in your React app, such as in a multi-step form or a wizard.

Image description

The Challenge

We aim to:

Add elements to an array in state each time the "Next" button is clicked.
Remove the last element from the array each time the "Back" button is clicked.
Manage the state of a currentScreen variable that updates based on the array index.
Ensure that the index resets upon reload and that the array updates dynamically with each button click.
The Implementation

import React, { useState, useEffect } from "react";

function MyComponent() {
  const [index, setIndex] = useState(0);
  const [nextArray, setNextArray] = useState([]);
  const [currentScreen, setCurrentScreen] = useState("");
  const [showTable, setShowTable] = useState(false);

  // Reset index to 0 on page reload
  useEffect(() => {
    setIndex(0);
  }, []);

  const handleNextClick = () => {
    setShowTable(true);
    setCurrentScreen(`showTable${index}`);
    console.log("Current Screen:", `showTable${index}`);

    setNextArray((prevArray) => [...prevArray, index + 1]);
    setIndex((prevIndex) => prevIndex + 1);
  };

  const handleBackClick = () => {
    // Remove the last element from the nextArray
    setNextArray((prevArray) => prevArray.slice(0, -1));

    // Decrease the index
    setIndex((prevIndex) => (prevIndex > 0 ? prevIndex - 1 : 0));

    // Adjust currentScreen accordingly
    if (index > 1) {
      setCurrentScreen(`showTable${index - 2}`);
    } else {
      setShowTable(false);
      setCurrentScreen("");
    }
  };

  return (
    <div style={styles.container}>
      <div style={styles.buttonContainer}>
        <button style={styles.button} onClick={handleNextClick}>
          Next
        </button>
        <button
          style={{ ...styles.button, ...styles.backButton }}
          onClick={handleBackClick}
          disabled={nextArray.length === 0}
        >
          Back
        </button>
      </div>
      <div style={styles.screenContainer}>
        {showTable && (
          <p style={styles.screenText}>Showing Table {currentScreen}</p>
        )}
      </div>
      <ul style={styles.list}>
        {nextArray.map((item, i) => (
          <li key={i} style={styles.listItem}>
            Element: {item}
          </li>
        ))}
      </ul>
    </div>
  );
}

const styles = {
  container: {
    fontFamily: "'Arial', sans-serif",
    background: "linear-gradient(135deg, #667eea, #8859b8)",
    padding: "20px",
    borderRadius: "8px",
    width: "300px",
    margin: "10rem auto",
    boxShadow: "0 2px 8px rgba(0, 0, 0, 0.1)",
  },
  buttonContainer: {
    display: "flex",
    justifyContent: "space-between",
    marginBottom: "20px",
  },
  button: {
    padding: "10px 20px",
    fontSize: "16px",
    color: "#000",
    backgroundColor: "#ddc8ffd6",
    border: "none",
    borderRadius: "4px",
    cursor: "pointer",
    transition: "background-color 0.3s",
  },
  backButton: {
    backgroundColor: "#6c757d",
    color: "#fff",
  },
  buttonHover: {
    backgroundColor: "#0056b3",
  },
  screenContainer: {
    textAlign: "center",
    marginBottom: "20px",
  },
  screenText: {
    fontSize: "18px",
    color: "#333",
  },
  list: {
    listStyleType: "none",
    padding: 0,
  },
  listItem: {
    padding: "10px",
    backgroundColor: "#fff",
    borderRadius: "4px",
    marginBottom: "10px",
    boxShadow: "0 1px 4px rgba(0, 0, 0, 0.1)",
  },
};

export default MyComponent;

Enter fullscreen mode Exit fullscreen mode

Step-by-Step Breakdown

1. Initializing State
We use the useState hook to define and manage our state variables:

index: Keeps track of the current index.
nextArray: Holds the elements added by the "Next" button.
currentScreen: Stores the current screen based on the index.
showTable: Controls whether the table is shown.

2. Resetting Index on Reload

Using useEffect, we ensure the index resets to 0 every time the component mounts, such as on a page reload.

3. Adding Elements with handleNextClick

When the "Next" button is clicked:

We set showTable to true.
Update currentScreen with "showTable" + index.
Add the current index to nextArray and increment the index for the next click.

4. Removing Elements with handleBackClick

When the "Back" button is clicked:

We remove the last element from nextArray using slice(0, -1).
Decrement the index if it’s greater than 0.
Adjust currentScreen to reflect the updated index or hide the table if the array is empty.
Handling Edge Cases
We disable the "Back" button when there are no elements left in nextArray. This prevents trying to remove elements from an empty array.

Conclusion

This implementation allows for smooth management of a state array in React, enabling dynamic addition and removal of elements based on button clicks. The useState and useEffect hooks help manage state and side effects effectively, ensuring a seamless user experience.

shop Link : https://buymeacoffee.com/pratik1110r/extras

LinkedIn : https://www.linkedin.com/in/pratik-tamhane-583023217/

Behance : https://www.behance.net/pratiktamhane

Top comments (2)

Collapse
 
gadekar_sachin profile image
Sachin Gadekar

nice

Collapse
 
uicraft_by_pratik profile image
Pratik Tamhane

Thank you❤️