Ibra
Ibra

Reputation: 1072

Remove last item in an Object in React state

I'm mapping out a state into input fields and have a handler to create a new input by adding to the state new objects. Is there a way to create a SINGLE button to remove the last object in the state? Appreciate your help !

 const [data, setData] = useState({
    datapoint1: "",
    datapoint2: "",
    datapoint3: "",
    datapoint4: ""   });

// This adds new objects to the state
    const handleClick = () => {
        setData({
          ...data,
          [`datapoint${Object.keys(data).length + 1}`]: ""
        });
      };
 

//This dynamically changes the input keys and value stored in state 
      const handleChange = (datapoint) => (event) =>
        setData({
          ...data,
          [datapoint]: event.target.value
        });


<button onClick={handleClick}>Click to add</button>

// I would like another button here to remove last input 

      {Object.keys(data).map((datapoint) => {
        return (
          <input
            style={{ margin: "20px" }}
            key={datapoint}
            onChange={handleChange(datapoint)}
          />
        );
      })}

Upvotes: 0

Views: 1158

Answers (2)

Cybershadow
Cybershadow

Reputation: 1177

Bear in mind that objects' cannot preserve the order of the keys.

If you need order preserved , you can use Maps instead

Here's a demo

import React, { useState } from "react";
import ReactDOM from "react-dom";

function App() {
  const [data, setData] = useState(
    new Map(
      Object.entries({
        datapoint1: "",
        datapoint2: "",
        datapoint3: "",
        datapoint4: ""
      })
    )
  );

  // This adds new objects to the state
  const handleClick = () => {
    const newData = new Map(data);
    newData.set(`datapoint${data.size + 1}`, "");
    setData(newData);
  };

  //This dynamically changes the input keys and value stored in state
  const handleChange = (datapoint) => (event) => {
    const newData = new Map(data);
    console.log({ newData });
    newData.set(datapoint, event.target.value);
    setData(newData);
  };
  const handleDelete = () => {
    const newData = new Map(data);
    newData.delete(`datapoint${data.size}`);
    setData(newData);
  };
  return (
    <React.Fragment>
      <button onClick={handleClick}>Click to add</button>
      <button onClick={handleDelete}>Click to rmeove last</button>
      // I would like another button here to remove last input
      {[...data.keys()].map((datapoint) => {
        return (
          <input
            style={{ margin: "20px" }}
            key={datapoint}
            onChange={handleChange(datapoint)}
          />
        );
      })}
    </React.Fragment>
  );
}

ReactDOM.render(<App />, document.getElementById("container"));

Upvotes: 2

Nisanth Reddy
Nisanth Reddy

Reputation: 6405

You are looking for the delete keyword for Js Objects

const removeLastStateItem = () => {
    let newData = { ...data };
    delete newData[`datapoint${Object.keys(data).length}`];
    setData(newData);
};

delete obj['my_key'] - remove the my_key key from the obj

Upvotes: 1

Related Questions