简体   繁体   English

使用 React useState 更改对象数组

[英]Changing an array of objects with React useState

I have a calendar app that renders its events with an array of objects:我有一个日历应用程序,它使用一组对象呈现其事件:

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

I am trying to allow the user to add new events with the inputs on the page.我试图允许用户使用页面上的输入添加新事件。 So far I am just trying to change the title of the event with this code到目前为止,我只是想用这段代码更改事件的标题

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

When I console.log(e.target.value) it gives me what I am typing in, but the (events.title) is giving me undefined.当我console.log(e.target.value)它给了我我正在输入的内容,但是(events.title)给了我未定义的内容。
My end goal is to have the user add new events with the inputs in the following format.我的最终目标是让用户使用以下格式的输入添加新事件。 If I'm on the wrong track, or you know a better way I'd love to hear it.如果我走错了路,或者你知道更好的方式,我很想听听。

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
    }

  ])

Thank you in advance, my full code is Here And here is a codesandbox:https://codesandbox.io/embed/gracious-minsky-pp1w5?codemirror=1提前谢谢你,我的完整代码在这里这里是一个代码框:https://codesandbox.io/embed/gracious-minsky-pp1w5?codemirror=1

I think that that console.log is missplaced, you shouldn't be calling that function inside an array assignment.我认为那个console.log放错了地方,你不应该在数组赋值中调用那个 function 。 And even if you call it below the setEvents function will not give you the title because the set function of the useState is asynchronous.即使你在 setEvents function 下面调用它也不会给你标题,因为 useState 的集合useState是异步的。 Also I think you are not doing right the assignment of the events into your array.另外我认为你没有正确地将事件分配到你的数组中。

In this line:在这一行:

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

You are spreading the events inside a new array and then adding the title, leaving you with a structure similar to this:您正在将事件传播到一个新数组中,然后添加标题,从而为您留下与此类似的结构:

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

And nesting this titles for every change in the input.并为输入中的每个更改嵌套此标题。

For the structure you want to achieve you must push a new entry into an array that already contains your previous events, and then update the state.对于您想要实现的结构,您必须将新条目推送到已包含先前事件的数组中,然后更新 state。 Like:喜欢:

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

You can see this idea working here: https://codesandbox.io/s/green-cherry-xuon7你可以在这里看到这个想法: https://codesandbox.io/s/green-cherry-xuon7

Your method of changing title is incorrect.您更改标题的方法不正确。 Since it is array of objects, you will need to get to the specific object and then change the particular title.由于它是对象数组,因此您需要找到特定的 object,然后更改特定的标题。 In your case replacing this code with yours helps in changing title of 0 index.在您的情况下,用您的代码替换此代码有助于更改 0 索引的标题。

<input
      placeholder="Name"
      onChange={(e) =>{
        let tempArr = [...events];
        tempArr[0].title = e.target.value;
        setEvents(tempArr)
      }}
      required
    >

If you also want to add new objects, push it in tempArr on some event and update setEvents.如果您还想添加新对象,请将其推送到某些事件的 tempArr 中并更新 setEvents。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM