当新数据被推入数组时更新功能组件



我有一个功能反应组件:

function Messages() {
return(
data.messages.map(function(obj, i){return(
<div className="messages_wrapper" key={i}>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
)})
)
}
export default Messages;

…它显示名为data的数组中包含的所有消息。数据对象看起来像这样:

export const data = {
messages : [
{
// data here
},
{
// data here
},
....
}

当我将新消息推入data时:

messages.data.push({
"message" : "this is a new message"
})

…我想让上面的组件呈现在DOM中。我相信这就是钩子的作用,特别是UseEffect钩子,但它似乎不起作用。

当数据数组有一个新元素推入它时,我怎么能让功能组件呈现自己?是否有一种方法可以让组件"监听"?更改数据对象并在更改时呈现自身?

const [count, newMessage] = useState(0);
useEffect(() => {
// do something with data array here?
});

您必须创建一个像这样的状态消息:

[messagesState, setMessagesState] = useState({ messages : [
{
// data here
},
{
// data here
},
....
]})

当你在数组中添加新项时,不要使用突变,使用可变数据,像这样:

const messagesUpdated =  {
messages : [...messagesState, newMessage]
}
setMessagesState(messagesUpdated)

在react中改变状态数据(更具体地说是引用类型)是一个禁忌你的messages数组确实是你的组件的状态,因为它取决于它和它的变化。您应该跟踪组件(或任何父组件)中的messages,并通过props将其传递给相关组件,并将更改为引用。对于它,不是数组本身的内容(为什么?下面解释)。

示例:

import React, { useState, useEffect } from 'react';
function Messages() {
const [messages, setMessages] = useState([]);
return (
{messages.map((message, index) => {
return (
<div className="messages_wrapper" key={i}>
/* use message here*/
</div>
);
})}
);
}
export default Messages;

现在,根据您希望如何向messages集合添加新消息(事件处理程序或任何其他类型的效果),您应该(通过setMessages函数)提供具有更新的引用的react它会自动为你处理组件的重新渲染。

示例:

const handleClick = () => {
const newMessage = {
/* message body */
};
setMessages((messages) => [...messages, newMessage]);
};

这样,每次执行handleClick处理程序时,setMessages函数将创建一个包含所有当前消息+您想要推送的新消息的新数组,并将该数组引用传递给状态messages变量。React会注意到messages变量引用发生了变化,并会重新执行函数组件的主体,从而重新呈现和呈现更新后的可视化。

把你的逻辑写得好像你所有的状态都是不可变的,唯一改变它的方法就是完全提供一个新的引用。这很重要,因为它确保react能够正确有效地跟踪和处理状态更改。引擎不跟踪中的变化对象本身,有一个非常好的性能和可维护性的原因,这种行为。这就是为什么你不应该改变引用变量的内容。

所以,简而言之,useState是一个维护状态的钩子。另一方面,useEffect关注的是执行的副作用(获取数据,订阅等等)。

如果这些消息是共享数据,并且由多个不相关的组件使用,或者仅由单个组件使用,这一点很重要。在后一种情况下,您可以将它们存储在如上所示的组件状态中,并从相关服务或任何您拥有的组件挂载中加载它们:

import React, { useState, useEffect } from 'react';
function Messages() {
const [messages, setMessages] = useState([]);
useEffect(() => {
const async fetchMessages = () => {
/* fetch logic */
const messagesResult = await _service.getMessages(); /* fetch logic */;
setMessages(messagesResult);
}
fetchMessages();
}, []);
return (
{messages.map((message, index) => {
return (
<div className="messages_wrapper" key={i}>
/* use message here*/
</div>
);
})}
);
}
export default Messages;

在前一种情况下,您应该在一个地方跟踪状态,并通知感兴趣的组件更改(通过将状态作为props传递给相关的子组件,或者通过将上下文/状态管理库传递给更复杂的情况)。

最新更新