开发者问题收集

如何在数组中添加对象作为属性(react.js)

2021-08-17
3242

首先,抱歉标题太令人困惑了。我找不到更清楚的表达方式。

最近,我正在做自己的项目,遇到了一个问题。如果你能给我一些建议,那对我来说将是一个巨大的帮助。

所以,这是我的状态

const[state, setState] = useState({
    externalEvents: [
      { title: "Art 1", color: "#0097a7", id: 34432, custom: "fdsfdsfds" },
      { title: "Art 2", color: "#f44336", id: 323232 },
      { title: "Art 3", color: "#f57f17", id: 1111 },
      { title: "Art 4", color: "#90a4ae", id: 432432 },
     
      
    ]
  });

这是我的输入标签和函数

<form className="todoinput"  onSubmit={addTodo} >
    <input type="text" value={title} onChange={e=>setTitle(e.target.value)} placeholder="Add event" />
    <input type="text" value={custom} onChange={e=>setCustom(e.target.value)} placeholder="detail" />
    <select>
      <option value={()=>{setColor('blue')}}>blue</option>
      <option value={()=>{setColor('orange')}}>orange</option>
      <option value={()=>{setColor('green')}}>green</option>
      <option value={()=>{setColor('purple')}}>purple</option>
    </select>
    <button  type="submit">Add todo</button>
  </form>


const addTodo = (e) =>{
    e.preventDefault();
    setState([...state.externalEvents,{title:{title}, color: {color}, custom: {custom}}])
    setTitle('')
    setCustom('')
  }

这就是我想要做的:我输入标题、自定义并在输入和选择标签中选择颜色。然后我提交它,然后函数将在 externalEvents(array) 中添加新对象 我使用 spread 来执行此操作,但不知何故它不起作用,控制台显示“TypeError:无法读取未定义的属性‘map’”

<div id="external-events">
          {state.externalEvents.map((event) => (
           <div 
           className="fc-event"
           title={event.title}
           data-id={event.id}
           data-color={event.color}
           data-custom={event.custom}
           key={event.id}
           style={{
             backgroundColor: event.color,
             borderColor: event.color,
             cursor: "pointer"
           }}
           >{event.title}</div>
            ))}
      </div>

这是 map() 发生的部分,我认为 map 无法读取属性的原因是因为 我未能将正确的属性发送到 externalEvents。

感谢您的阅读,您的帮助将不胜感激。

附言:我使用了 FullCalendar 库!

3个回答

初始化状态时,它是一个带有键 externalEvents 的对象,该键是一个数组

useState({
    externalEvents: [
      { title: "Art 1", color: "#0097a7", id: 34432, custom: "fdsfdsfds" },
      { title: "Art 2", color: "#f44336", id: 323232 },
      { title: "Art 3", color: "#f57f17", id: 1111 },
      { title: "Art 4", color: "#90a4ae", id: 432432 },  
    ]
  })

但是,当您更新状态时,它是一个数组

setState([...state.externalEvents,{title:{title}, color: {color}, custom: {custom}}])

因此,根据您的初始状态, setState 应如下所示

setState({
  ...state, 
  externalEvents: [
    ...state.externalEvents, 
    {title, color, custom}
  ]})

请注意, {title, color, custom 可能是您想要的,而不是 {title: {title}, xxxx

Isaac
2021-08-18

您的问题可能出在您的 addTodo 函数中。

此函数将 state 设置为数组。此后, state.externalEvents 不再存在。 要测试这一点,请在 addTodo 函数中设置 console.log(state) 后尝试它。

根据您的意图,下面是对 addTodo 函数的修改,可能会解决您的问题:

const addTodo = (e) =>{
    e.preventDefault();

    // Use previous state, and make sure to return an object with an 'externalEvents' key as the new state
    setState((prevState) => {
        const newEvent = {} // whatever your new event is
        return { externalEvents: [...prevState.externalEvents, newEvent] }

    })
    setTitle('')
    setCustom('')
}

进一步改进

此外,您可以通过直接拥有 externalEvents 状态来使事情变得更简单,从而无需在其他状态对象中嵌套 externalEvents 属性。

例如:

const [externalEvents, setExternalEvents] = useState([
      { title: "Art 1", color: "#0097a7", id: 34432, custom: "fdsfdsfds" },
      { title: "Art 2", color: "#f44336", id: 323232 },
      { title: "Art 3", color: "#f57f17", id: 1111 },
      { title: "Art 4", color: "#90a4ae", id: 432432 } 
    ])

如果采用这种方法,则需要再次更新 addTodo 函数,特别是状态更新步骤。

您的状态更新步骤现在看起来像这个:

setExternalEvents((prevExternalEvents) => {
        const newEvent = {} // whatever your new event is
        return [...prevExternalEvents, newEvent]
    })

更多信息请参见此处:

  1. 根据先前状态设置状态: useState 钩子,setState 函数。访问先前的状态值
rexess
2021-08-18

我认为问题在于您将状态定义为一个对象,其键为 externalEvents,它是一个数组。但是当您提交表单时,在 setState 函数中,您设置的是一个数组,而不是原始形状。

我建议您这样做:

const [externalEvents, setExternalEvents] = useState([
  { title: "Art 1", color: "#0097a7", id: 34432, custom: "foo" },
  { title: "Art 2", color: "#f44336", id: 323232 },
  { title: "Art 3", color: "#f57f17", id: 1111 },
  { title: "Art 4", color: "#90a4ae", id: 432432 },
]);

并在表单中:

const addTodo = (e) => {
  ...
  setExternalEvents(prev => [...prev, {title, color, custom}])
  ...
}
Oswaldo Martinez
2021-08-18