Redux,react native:相等函数不消除不必要的重新呈现

1tu0hz3e  于 2023-10-19  发布在  React
关注(0)|答案(1)|浏览(96)

使用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
        }
    }
});
iq0todco

iq0todco1#

这是因为你的数组是 * 不 * 浅等于对方。
useSelector中返回一个新的数组引用是可以的,* 如果 * 你使用shallowEqual而不是默认的引用比较**。

  • 然而 * 你把对象的 * 副本 * 放入这个数组中。这意味着旧数组和新数组 * 不是 * 浅相等的。浅相等意味着firstArray[i] === secondArray[i],对于每个索引,这里不会是这种情况。

相关问题