通过网络套接字多次接收同一条消息.在3条或4条新聊天信息后,旧信息将被替换



我正在将web套接字集成到React中,并在后台使用Django。

我可以发送消息,也可以从后端接收新消息。

问题是,在发送3或4条消息后,以前的消息会被前端的新消息取代,但后端一切都很好,事实上,刷新后一切都正常。

如何在这种情况下正确更新状态?

编辑:

我现在发现的主要问题是,当我发送聊天时,状态会多次更新,每次它的长度都会变化,屏幕会抖动很多。

切片

name: 'chat',
initialState: {
chatMessages: [],
}
reducers: {
setChatMessages(state, action) {
const chatmessages = action.payload;
return {...state, chatMessages:chatmessages}; 
},
}

聊天

const chatMessagesSelector = useSelector(selectChats);
const chatMessages = chatMessagesSelector?.chatMessages
chatSocket.onmessage = (e) => {
var data = JSON.parse(e.data)
var message = {message: data.message, user: data.user,
timestamp: data.timestamp};  
//console.log(message)
let updatedMessages = [...chatMessages];
updatedMessages.push(message);
dispatch(setChatMessages(updatedMessages));
}

这是记录在updatedMessages之上的chatMessages对象。

Array(1)
0: {user: "testuser", message: "check!", timestamp: "2021-03-09T09:15:09.408717+01:00}
length: 1

以下代码(方法1*(:

chatSocket.onmessage = (e) => {
var data = JSON.parse(e.data)
var message = {message: data.message, user: data.user, timestamp: data.timestamp};
let updatedMessages = [...chatMessages];
updatedMessages.push(message);
dispatch(setChatMessages(updatedMessages));

从redux中读取并创建新的Array,推送新元素并分派整个数组。

相反,(方法2(,您可以只发送新的元素,由reducer:推送到redux存储

chatSocket.onmessage = (e) => {
var data = JSON.parse(e.data)
var message = {message: data.message, user: data.user, timestamp: data.timestamp};   
dispatch(setChatMessages(message));

现在(对于方法2(,您需要在减速器中进行此更改:

reducers: {
setChatMessages(state, action) {
return {...state, chatMessages: [...state.chatMessages, action.payload]};}
}

你也可以这样做:

reducers: {
setChatMessages(state, action) {
state.chatMessages.push(action.payload)
}

因为:

Redux Toolkit允许我们编写;突变";减速器中的逻辑。它实际上并没有改变状态,因为它使用了Immer库,其检测到"0"的变化;草稿状态";并生产全新基于这些变化的不可变状态

*如果组件中的chatMessages已过时或延迟,则方法1可能会出现错误。

编辑:

真正的问题似乎是您的事件侦听器被多次注册

要修复它,您应该将其移动到useEffectcomponentDidMount:

useEffect(() => {
chatSocket.onmessage = (e) => {
var data = JSON.parse(e.data)
// ...
}
return function cleanup() {
// de-register the socket event
}
}, [])

您需要将新消息与旧消息连接起来,但您正在替换它们:

setChatMessages(state, action) {
const chatMessages = action.payload;
return { ...state, chatMessages: state.chatmessages.concat(chatMessages)};
}

若您在本地存储相同的消息,然后从套接字发回,请小心并避免重复。

相关内容

  • 没有找到相关文章

最新更新