React 钩子:嵌套在 for 循环中的 useState、Updater 函数不更新状态

时间:2021-03-24 22:40:44

标签: reactjs react-hooks react-state array.prototype.map

我有一个 useEffect 钩子,我在其中按换行符从状态拆分字符串以创建数组,

该数组正在循环,我想要的是将一个对象添加到我的状态/钩子 (messageContainer) 和 id 和一个消息属性,例如 {id: i, message: messageRow[i]} 如果它不存在或更新如果它存在,例如 return {...messageObj, message: messageRow[i]}

const [messages, setMessages] = useState('');

const [messagesContainer, setMessagesContainer] = useState([])

useEffect(() => {
var messageRow = messages.split('\n');

for (let i = 0; i < messageRow.length; i++) {
    setMessagesContainer(previousState => (
        [...previousState,
            ...previousState.map((messageObj, index, arr) => {
                if (messageObj.id === i) {
                    return {
                        ...messageObj,
                        message: messageRow[i]
                    }
                } else {
                    return {
                        id: i,
                        message: messageRow[i]
                    }
                }
            })
        ]
    ))
}
}, [messages])

messagesContainer 是空的?

如果数组具有具有该属性的对象,我该如何更新它,或者如果它不存在,我该如何添加它?

先谢谢你!

更新:

正如 Bart 在下面提到的,我应该初始化 messageContainer

所以我做到了:

const [messagesContainer, setMessagesContainer] = useState([{id: 0, messages: null}])

但现在它只是附加到数组而不更新同一个对象:

enter image description here

1 个答案:

答案 0 :(得分:1)

在 useEffect 中尝试类似下面的代码。它会起作用。

useEffect(() => {
var messageRow = messages.split("\n");
let allMessages = [...messagesContainer]
for (let i = 0; i < messageRow.length; i++) {
  let match = allMessages.filter(item=>item.id===i);
  if(match?.length){
    match[0].messages=messageRow[i];
  }
  else{
    allMessages.push({id:i,messages:messageRow[i]})
  }
}
console.log(allMessages);
setMessagesContainer(allMessages);
}, [messages]);