简体   繁体   English

使用 Hooks 替换而不是 concat 在 React 上更新数组 State

[英]Update Array State on React using Hooks replaces instead of concat

I have this hook:我有这个钩子:

const [pastChat, setPastChat] = useState([]);

I'm updating it with a function that it's called when the user presses a button:我正在使用 function 更新它,当用户按下按钮时会调用它:

const nextAction = (step) => {
    //...do a bunch of things...
    let nextInLine = [array with an object];
    setPastChat(pastChat.concat(nextInLine));
}

This code works just fine, but when I try to run this setPastChat() in a loop (while or for loop) it just replaces the last item instead of concat() it.这段代码工作得很好,但是当我尝试在循环(while 或 for 循环)中运行这个setPastChat()时,它只是替换了最后一项而不是concat()它。 I'm using concat because push() does not work as well.我使用 concat 是因为push()也不能正常工作。 So I have something like this:所以我有这样的事情:

const nextActionLoop = (step) => {
    //...do a bunch of things...
    let nextInLine = [array with an object];
    let index = 0;
    while(index < 5) {
        //...change nextInLine's object;
        setPastChat(pastChat.concat(nextInLine));
        index = index + 1;
    }
}

I'm not sure why this is happening, but I tried to log pastState and even in the function that works the state appears not the be updated after setPastChat(pastChat.concat(nextInLine));我不确定为什么会发生这种情况,但我试图记录pastState ,甚至在 function 中工作 state 似乎不会在setPastChat(pastChat.concat(nextInLine));之后更新。 . . It does update my view correctly, but it might do this a while after.它确实正确地更新了我的视图,但它可能会在一段时间后这样做。 I have no idea and I'd like to know how can I just concat new items in the while loop, please.我不知道,我想知道如何在 while 循环中连接新项目,拜托。

I thank you in advance!我提前谢谢你!

Use a functional state update to correctly enqueue multiple state updates.使用功能性 state 更新正确地将多个 state 更新加入队列。 The issue is that all the queued updates use the same pastChat state value from the current render cycle, so each update overwrites the previous one and the last update is the one you see.问题是所有排队的更新都使用当前渲染周期中相同的pastChat state 值,因此每次更新都会覆盖前一个更新,而最后一个更新就是您看到的更新。

const nextActionLoop = (step) => {
    //...do a bunch of things...
    let nextInLine = [array with an object];
    let index = 0;
    while(index < 5) {
        //...change nextInLine's object;
        setPastChat(pastChat => pastChat.concat(nextInLine));
        index = index + 1;
    }
}

This will use the previous state and compute the next state value.这将使用之前的 state 并计算下一个 state 值。

Here's a demo of mine that demonstrates the difference between a regular update and a functional update, and why the functional update works for multiple enqueued updates.这是我的一个演示,它演示了常规更新和功能更新之间的区别,以及为什么功能更新适用于多个排队更新。

编辑反应 - 定期和功能状态更新

I don't know the process time in your loop, but if it's not slow and sync, you should first concat all your pastChat and then update the state:我不知道您循环中的处理时间,但如果它不慢且不同步,您应该首先连接所有过去的聊天,然后更新pastChat

const nextActionLoop = (step) => {
    //...do a bunch of things...
    const iterations = 5;
    const newPastChat = Array(iterations).fill().map((_, i) => {
      const nextInLine = {...};

      return nextInLine;
    });

    setPastChat(newPastChat);
}

btw you're free of mutations, only functional code;)顺便说一句,您没有突变,只有功能代码;)

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

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