首页 > 解决方案 > onclick 我的提交按钮,存储在 localstorage 中的数组不会添加新项目,而是在使用 react 时被替换

问题描述

我正在尝试将来自单个输入字段的数据添加到要存储在本地存储中的数组中,但是当我提交输入按钮时,该项目首先存储,但如果我尝试存储第二个项目,则数组上一个项目是替换为新键入的项目数据,而不是像我期望的数组那样添加到它。我不明白这种行为。我真的很感激详细的解释,因为我正在使用 react 来做到这一点。这是我下面的代码

输入字段

    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;

*这是我将输入数据添加到本地存储的代码*


  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 });
  };
``

    

标签: javascriptarraysreactjssetstate

解决方案


Array.prototype.push当然会改变数组,但它的返回值不是数组,而是数组的新长度。您可能希望将突变与 JSON 序列化分开。

覆盖的原因是因为您使用两个不同的存储密钥来获取和设置。您没有得到存储的内容,因此您只是将新数据附加到一个空数组。确保您还使用相同的密钥来检索设置 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 });
};

更优化的解决方案是optionslocalStorage 读入并初始化状态,并使用挂钩将状态更新持久化localStorage。这种方式更容易管理。useEffect

例子:

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),
  }));
};

推荐阅读