onclick of my submit button, the array stored in localstorage does not add the new item but is replaced while using react

Viewed 655

I'm trying to add data from a single input field to an array which i want to store in localstorage but when i submit input button, the item is stored at first but if i try to store a second item, the array previous item is replaced with the newly typed item data instead of adding to it like i'd expect an array to behave. i don't understand this behaviour. i will really really appreciate a detailed explanation since i'm using react to do this. This is my code below

input field

    import React from "react";
import "./addoption.css";

function AddOption({ validateOption }) {
  const handleAddoption = (e) => {
    e.preventDefault();
    const inputValue = e.target.elements[0].value.trim();
    validateOption(inputValue);
    e.target.elements[0].value = "";
  };

  return (
    <div className="addoption">
      <form onSubmit={handleAddoption}>
        <input type="text" name="list" />
        <button>Add Option</button>
      </form>
    </div>
  );
}

export default AddOption;

*this is my code to add the input data to the localstorage *


  const handleAddoption = (option) => {
    if (!option) {
      return setErrorhandler("Enter valid value to add item");
    } else if (listItems.options.indexOf(option) > -1) {
      return setErrorhandler("This option already exists!");
    }
    const array = localStorage.getItem("Options");
    let items = [];
    if (array) {
      items = JSON.parse(array);
    }
    let storedArray = JSON.stringify(items.push(option));

    localStorage.setItem("options", storedArray);

    setListItems({ options: items });
  };
``

    
1 Answers

Array.prototype.push certainly mutates the array, but it's return value isn't the array, it's the new length of the array. You may want to do the mutation separate from the JSON serializing.

The reason for the overwriting is because you're using two different storage keys for getting and setting. You are not getting what was stored so you are only appending new data to an empty array. Make sure you also use the same key to both retrieve and set the localStorage.

const handleAddoption = (option) => {
  if (!option) {
    return setErrorhandler("Enter valid value to add item");
  } else if (listItems.options.indexOf(option) > -1) {
    return setErrorhandler("This option already exists!");
  }
  const array = localStorage.getItem("options");
  let items = [];
  if (array) {
    items = JSON.parse(array);
  }

  items.push(option);

  localStorage.setItem("options", JSON.stringify(items));

  setListItems({ options: items });
};

A more optimal solution would be to read in and initialize the options state from localStorage, and use an useEffect hook to just persist state updates back to localStorage. This way is a little easier to manage.

Example:

const initializeState = () => ({
  // ... other listItems initial state
  options: JSON.parse(localStorage.getItem("options")) || [],
});

const [listItems, setListItems] = useState(initializeState());

useEffect(() => {
  localStorage.setItem("options", JSON.stringify(listItems.options));
}, [listItems.options]);

const handleAddoption = (option) => {
  if (!option) {
    return setErrorhandler("Enter valid value to add item");
  } else if (listItems.options.indexOf(option) > -1) {
    return setErrorhandler("This option already exists!");
  }
  
  setListItems(prevState => ({
    ...prevState
    options: prevState.options.concat(option),
  }));
};
Related