簡體   English   中英

React - 更新狀態數組

[英]React - update state array

語境

你好,

我正在創建一個表單來創建虛擬機。 信息跨多個頁面(組件)收集並集中在頂級組件中。

它的狀態對象如下所示:

const [vmProp, setVmProp] = useState({
    name: "",
    image_id: "",
    image_name: "",
    volumesList: [],
    RAM: "",
    vcpu: "",
    autostart: true,
    });

問題

我希望能夠在卷列表中添加/刪除卷,並且我希望卷列表看起來像這樣:

[
    {
      name: "main",
      size: 1024
    },
    {
      name: "backup",
      size: 2048
    },
    {
      name: "export",
      size: 2048
    }
]

我試過的

現在我只嘗試添加一個音量。

1:工作但不產生我想要的

const handleAddVolume = (obj) => {
    setVmProp({ ...vmProp,
        volumesList: {
            ...vmProp.volumesList,
            [obj.name]: {
                size: obj.size,
            },
        } });
};

它正在工作,但輸出是:

[
    name: {
      size: 1024
    }
]

2 : 應該工作,但它不是

const handleAddVolume = (obj) => {
    setVmProp({ ...vmProp,
        volumesList: {
            ...vmProp.volumesList,
            {
                name: obj.name,
                size: obj.size,
            },
        } });
};

輸出 :

[
    name: "main",
    size: 1024

]

您對如何處理此類狀態對象有任何想法嗎? 謝謝

如果您不需要從其他狀態嵌套/取消嵌套卷列表,您將擁有更好的時間。 (更慣用的方法是為這些值中的每一個都設置一個狀態原子,但對於簡單的值,例如布爾值和字符串,就可以了。)

const [vmProps, setVmProps] = useState({
  name: "",
  image_id: "",
  image_name: "",
  RAM: "",
  vcpu: "",
  autostart: true,
});
const [volumesList, setVolumesList] = useState([]);

volumesList不應該是對象,將其作為handleAddVolume函數內的數組。

試試下面的方法,

const handleAddVolume = (obj) => {
    setVmProp({ ...vmProp,
        volumesList: [
            ...vmProp.volumesList,
            {
                name: obj.name,
                size: obj.size,
            }
        ] });
};

這是一個工作示例:

const Example = (props) => {
  const inputRef = createRef();
  const [vmProp, setVmProp] = useState({
    name: "",
    image_id: "",
    image_name: "",
    volumesList: [],
    RAM: "",
    vcpu: "",
    autostart: true,
  });

  const { volumesList } = vmProp;

  const handleAddVolume = (e) => {
    e.preventDefault();
    const input = inputRef.current.value;
    setVmProp((prevVmProp) => {
      const newVmProp = { ...prevVmProp };
      newVmProp.volumesList.push({
        name: input,
        size: 1024,
      });
      return newVmProp;
    });
    // reset the input
    inputRef.current.value = "";
  };

  return (
    <>
      <form>
        <input ref={inputRef} type="text" />
        <button onClick={handleAddVolume}>Add volume</button>
      </form>
      {volumesList.map((volume) => (
        <div key={volume.name}>{`${volume.name} - ${volume.size}`}</div>
      ))}
    </>
  );
};

export default Example;

這只是一個概念證明。 基本上, setVmProp接受一個函數,該函數在更新是 asynchornus 時獲取最新狀態值並返回狀態的新值。 因此,使用ES6 的解構函數,我復制了名為newVmPropvmProp的最新值,然后將一個新對象推送到newVmProp.volumesList然后返回包含新添加的卷 + 其他所有內容的newVmProp 我從輸入字段獲得的name的值。 同樣,這只是一個概念證明。

由於我需要能夠在我的數組中添加/刪除/替換一個對象,我決定創建它自己的狀態如下:


const [volumesList, setVolumesList] = useState([]);

const handleAddVolume = (obj) => {
    setVolumesList((oldList) => [...oldList, obj]);
};

const handleRemoveVolume = (obj) => {
    setVolumesList((oldList) => oldList.filter((item) => item.name !== obj.name));
};

const handleEditVolume = (obj) => {
    setVolumesList(
        volumesList.map((volume) =>
            (volume.name === obj.name
                ? { ...volume, ...obj }
                : volume),
        ),
    );
};

感謝您的所有回答!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM