首页 > 解决方案 > 使用 React useState 更改对象数组

问题描述

我有一个日历应用程序,它使用一组对象呈现其事件:

const [events, setEvents] = useState([
    {
      title: "Werk",
      start: moment().toDate(),
      end: moment(),
      allDay: false,
    },
  ])

我试图允许用户使用页面上的输入添加新事件。到目前为止,我只是想用这段代码更改事件的标题

<input
          placeholder="Name"
          onChange={(e) =>
            setEvents([{ ...events, title: e.target.value }, console.log(events.title)])
          }
          required
        ></input>

当我console.log(e.target.value)给我输入的内容时,它(events.title)给了我未定义的内容。
我的最终目标是让用户使用以下格式的输入添加新事件。如果我走错了路,或者你知道更好的方式,我很想听听。

const [events, setEvents] = useState([
    {
      title: "Werk",
      start: moment().toDate(),
      end: moment(),
      allDay: false,
    },
// this is what the user will add 
    {
    title: "Example",
      start: Number,
      end: Number
    }

  ])

提前谢谢你,我的完整代码在这里这里是一个代码框:https ://codesandbox.io/embed/gracious-minsky-pp1w5?codemirror=1

标签: javascriptarraysreactjsuse-state

解决方案


我认为那console.log是放错地方了,您不应该在数组赋值中调用该函数。而且即使你在 setEvents 函数下面调用它也不会给你标题,因为 set 函数useState是异步的。另外我认为你没有正确地将事件分配到你的数组中。

在这一行:

setEvents([{ ...events, title: e.target.value }, console.log(events.title)])

您正在将事件传播到一个新数组中,然后添加标题,从而为您留下与此类似的结构:

[{
    "0": {
        "title": "Werk",
        "start": "2020-12-05T05:12:57.931Z",
        "end": "2020-12-05T05:12:57.931Z",
        "allDay": false
    },
    "title": "myNewTitle"
}]

并为输入中的每个更改嵌套此标题。

对于您想要实现的结构,您必须将新条目推送到已经包含先前事件的数组中,然后更新状态。喜欢:

//I think the best approach is calling this in a submit or button click event
const buttonClick = () => {
  const newEvents = [...events]; //This spreads every element inside the events array into a new one
  newEvents.push({
    title: eventTitleState, //You also need a useState for the title
    start: moment().toDate(),
    end: moment(),
  });
  setEvents(newEvents);
}

你可以在这里看到这个想法:https ://codesandbox.io/s/green-cherry-xuon7


推荐阅读