替换状态数组后使用useEffect来更新子组件的正确方法

时间:2019-10-26 05:10:25

标签: reactjs react-hooks use-effect

我有一个父组件“ Checkout”,在其中调用事件票证的api并将数据保存到状态。我有一个简单的功能,可以将现有的票证信息添加到用户选择的票证中。

结帐组件

    const handleTicketAdd = (e) => {
    // create new ticket array
    const newTickets = tickets;
    // 
    newTickets[e.target.id].count++;
    console.log(newTickets);
    setTickets(newTickets);
    console.log(tickets);
  }

此函数作为prop传递给子组件“ Tickets”,并在映射行中调用。

该功能运行良好,正在控制台中更新计数状态,但是子组件未重新呈现,并且屏幕上的值保持初始值。

我一直在研究,发现componentWillReceiveProps已替换为useEffect挂钩。我一直试图让它在我的子组件中正常工作而没有成功:

票务组件

useEffect(()=>{
    console.log("Tickets Changed", props.tickets);
}, [props.tickets]);

当props.tickets更改时,日志不会触发,因此我知道我没有正确处理此问题。有人可以指出我正确的方向。

更新

基于以下反馈,我已经修改了代码,并且代码已接近完成。问题在于,它正在使用对象的计数值在数组中添加一个新字段,而不是仅更新对象的count字段。

setTickets(prevTickets => ([...prevTickets, prevTickets[e.target.id].count = prevTickets[e.target.id].count + 1])
  )

如果我尝试弹出最后一个值之类的操作,则会将更多新字段添加到数组中。我将如何删除正在生成的其他字段。以下内容不起作用:

    setTickets(prevTickets => ([...prevTickets, prevTickets[e.target.id].count = prevTickets[e.target.id].count + 1], prevTickets.pop()),
  )


    setTickets(prevTickets => ([...prevTickets, prevTickets[e.target.id].count = prevTickets[e.target.id].count + 1], prevTickets.slice(-1)[0),
  )

2 个答案:

答案 0 :(得分:1)

您不应该在更新时改变状态,而是需要克隆和更新状态

const handleTicketAdd = (e) => {
    const id = e.target.id;
    setTickets(prevTickets => ([
         ...prevTickets.slice(0, id),
         {
             ...prevTickets[id],
             count: prevTickets[id].count + 1
          }
         ...prevTickets.slice(id + 1);
    ]));
  }

答案 1 :(得分:0)

好的,因此看起来应该使用map函数或使用先前状态的循环来完成编辑数组处于状态的方式。我能够根据Shubham的反馈进行解决。

// update count based on previous state 
  setTickets(prevTickets => (prevTickets.map((ticket, index) => {
    console.log(index, e.target.id);
    // if mapped object's id equals the arrays index, it's the value to edit
    if (e.target.id == index) {
      console.log(index);
      const count = ticket.count + 1;
      // return object with updated count values
      return { ...ticket, count }
    }
    return ticket;
  })
  ))

这使我可以对数组中所需的对象值进行编辑,而无需任何其他字段或值。