React 更新状态的对象数组属性

问题描述 投票:0回答:1

我有一个处于 React 状态的对象:

{
    name: "",
    price: 0.0,
    components: [],
 }

并且我正在尝试修改其

components
属性。我可以在调试器中看到状态已更新但渲染未更新,因此未渲染不同的嵌套对象。

我想这与这里描述的非常相似:

但我有一种感觉,我正在做预先知道的事情,使用更新程序功能,但它不起作用。

这是代码:

import React, { useState } from "react";

import "./styles.css";

defaultComponent = {
  name: "C1",
  comment: "",
}

export default function App() {

  const [system, setSystem] = useState({
    name: "",
    price: 0.0,
    components: [],
  })

  function modifySystemProperty(property, newValue) {
    let modifiedSystem = { ...system };
    modifiedSystem[property] = newValue;
    setSystem(modifiedSystem);
  }

  function addComponent() {
    setSystem((system) => ({
      ...system,
      components: [...system.components, defaultComponent],
    }));
};

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h3>Edit system:</h3>
      <form>
        <div>
          <label htmlFor="form-name">Name: </label>
          <input
            id="form-name"
            type="text"
            value={system?.name}
            onChange={(e) => modifySystemProperty("name", e.target.value)}
          />
        </div>
        <div>
          <label htmlFor="form-price">Price: </label>
          <input
            id="form-price"
            type="number"
            min="0"
            step="0.1"
            value={system?.price}
            onChange={(e) => modifySystemProperty("price", +e.target.value)}
          />
        </div>
        <div>
          <p>Components:</p>
          <ul>
            {system.components.map((c, idx) => {
              <li key={idx}>Component: {c.name}</li>
            })}
          </ul>
          <button
            onClick={() => addComponent()}
          >
            + Add Component
          </button>
        </div>
      </form>
    </div>
  );
}

并在 CodeSandBox 上运行:https://codesandbox.io/p/sandbox/thirsty-paper-jzsjfy 您能告诉我更新此对象属性的正确方法吗? 谢谢。

reactjs react-hooks
1个回答
0
投票

我至少看到两个问题:

  1. 每次单击您的按钮都会刷新页面。这是因为表单内的单个按钮默认为
    type="submit"
    。您需要将其更改为
    <button type="button">
  2. 您的
    system.components.map()
    循环不会渲染任何内容。您可以 (i) 在循环体内添加
    return
    语句,或者 (ii) 将大括号
    {}
    更改为圆括号
    ()
    。例如
{system.components.map((c, idx) => (
  <li key={idx}>Component: {c.name}</li>
))}

第三,我认为一旦开始编辑组件,每次向数组添加相同的

defaultComponent
都会产生问题,因为您正在重用相同的对象。我建议每次添加一个新对象。即

function addComponent() {
  setSystem((system) => ({
    ...system,
    components: [...system.components, {
      name: "C1",
      comment: "",
    }],
  }));
};
© www.soinside.com 2019 - 2024. All rights reserved.