使用redux,我有一个这样的消息存储:
import { createSlice } from "@reduxjs/toolkit";
const messagesSlice = createSlice({
name: "messages",
initialState: {
messagesData: {}
},
reducers: {
setChatMessages: (state, action) => {
const existingMessages = state.messagesData
const {chatId, messagesData} = action.payload
existingMessages[chatId] = messagesData
state.messagesData = existingMessages
}
}
});
export const setChatMessages = messagesSlice.actions.setChatMessages;
export default messagesSlice.reducer;
我使用dispatch在一个函数中设置状态,如下所示:
dispatch(setChatMessages({chatId, messagesData}))
我像下面这样访问这个状态。我实际上创建了一个数组,然后循环访问作为chatMessages的一部分存储的键,并将相应的值存储在一个数组中,并尝试返回这个数组。
const chatMessages = useSelector(state => {
if (!chatId) return []
const chatMessagesData = state.messages.messagesData[chatId]
if (!chatMessagesData) return []
const messageList = []
for (const key in chatMessagesData) {
const message = chatMessagesData[key]
messageList.push({
key,
...message
})
return messageList
}
}, {equalityFn: shallowEqual})
在最初运行这段代码时,我得到了错误:
WARN Selector unknown returned a different result when called with the same parameters. This can lead to unnecessary rerenders.
Selectors that return a new reference (such as an object or an array) should be memoized:
我添加了shallowEqualequality函数来尝试处理这个问题,它在我的应用程序中的其他情况下也可以工作,但在这种情况下无法解决这个问题。有解决这个问题的方法吗?谢谢.
编辑:
export const getAllChatMessages = (state) => state.messages.messagesData
export const selectSpecificChatMessages = createSelector([getAllChatMessages, (state, chatId) => chatId], (messages, chatId) => {
if (!chatId) return []
const chatMessagesData = messages[chatId]
if (!chatMessagesData) return []
const messageList = []
for (const key in chatMessagesData) {
const message = chatMessagesData[key]
messageList.push({
key,
...message
})
return messageList
}
})
使用新的选择器:
const chatMessages = useSelector(state => selectSpecificChatMessages(state, chatId))
编辑2:这显示了分派是如何发生的:
dispatch(setChatMessages({chatId, messagesData}))
这显示了如何设置减速器:
const messagesSlice = createSlice({
name: "messages",
initialState,
reducers: {
setChatMessages: (state, action) => {
const existingMessages = state.messagesData
const {chatId, messagesData} = action.payload
existingMessages[chatId] = messagesData
state.messagesData = existingMessages
}
}
});
1条答案
按热度按时间iq0todco1#
这是因为你的数组是 * 不 * 浅等于对方。
在
useSelector
中返回一个新的数组引用是可以的,* 如果 * 你使用shallowEqual
而不是默认的引用比较**。firstArray[i] === secondArray[i]
,对于每个索引,这里不会是这种情况。