React (Next) 不会在 redux 状态更改后重新渲染(是的,状态作为新对象返回)

React (Next) won't re-render after redux state change (yes, state returned as new object)

我的 NextJS 应用程序发生状态更改后,重新呈现 时遇到问题。

函数 sendMessageForm 启动一个 redux 动作 sendMessage 将消息添加到状态。
问题与减速器中的返回状态无关,因为我正在返回一个新对象(return {...state}),它应该触发重新渲染!

有什么可能会阻止重新渲染吗?
这是调用和显示状态的文件,所以没有其他文件应该负责!但如果您认为问题可能出在其他地方,请务必提及!

import { AttachFile, InsertEmoticon, Mic, MoreVert } from '@mui/icons-material';
import { Avatar, CircularProgress, IconButton } from '@mui/material';
import InfiniteScroll from 'react-infinite-scroller';
import Head from 'next/head';
import { useState, useEffect } from 'react';
import Message from '../../components/Message.component';
import styles from '../../styles/Chat.module.css'
import { useRouter } from 'next/router'
import {useSelector, useDispatch} from "react-redux"
import {bindActionCreators} from "redux"
import * as chatActions from "../../state/action-creators/chatActions"

const Chat = () => {
  const router = useRouter()
  const { roomId } = router.query

  const auth = useSelector((state)=> state.auth)
  const messages = useSelector((state)=> state.chat[roomId].messages)

  const dispatch = useDispatch()
  const {getMessages, markAsRead, sendMessage} = bindActionCreators(chatActions, dispatch)

  const [inputValue, setInputValue] = useState("")
  

  const sendMessageForm = (e) => {
      e.preventDefault()
      console.log("***inputValue:", inputValue)

      sendMessage(roomId, inputValue)
  }

  const loadMessages = (page) => {
      if(roomId)
        getMessages(roomId, page)
  }

  //user-read-message
  useEffect(() => {
    //user-read-message
    markAsRead(roomId, auth.user._id)
  }, [messages]);

  return (
    <div className={styles.container}>
        <Head>
            <title>Chat</title>
        </Head>

        <div className={styles.header}>
            <Avatar/>
            <div className={styles.headerInformation}>
                <h3>Zabre el Ayr</h3>
                <p>Last Seen ...</p>
            </div>
            <div className={styles.headerIcons}>
                <IconButton>
                    <AttachFile/>
                </IconButton>

                <IconButton>
                    <MoreVert/>
                </IconButton>
            </div>
        </div>

        <div className={styles.chatContainer}>
            <InfiniteScroll
                isReverse={true}
                pageStart={0}
                loadMore={loadMessages}
                hasMore={messages.hasNextPage || false}
                loader={<div className={styles.loader} key={0}><CircularProgress /></div>}
            >
                {Object.keys(messages.docs).map((key, index)=>{
                return<Message
                    key={index}
                    sentByMe={messages.docs[key].createdBy === auth.user._id}
                    message={messages.docs[key].msg}
                />})}
            </InfiniteScroll>
            <span className={styles.chatContainerEnd}></span>
        </div>

        <form className={styles.inputContainer}>
            <InsertEmoticon/>
            <input className={styles.chatInput} value={inputValue} onChange={(e)=>setInputValue(e.target.value)}/>
            <button hidden disabled={!inputValue} type='submit' onClick={sendMessageForm}></button>
            <Mic/>
        </form>
    </div>)
};

export default Chat;

useSelector 需要一个新对象,其中包含您传递给它的对象的新引用,以便触发 re-render

你用 return {...state} 做的只是为父对象创建一个新对象,而不是 useSelector 正在使用的嵌套对象,在你的情况下是这样的:

const messages = useSelector((state)=> state.chat[roomId].messages)

因此,您应该 return 将整个状态作为一个新对象和一个新的 state.chat[roomId].messages 对象

换句话说,应该更改根对象和正在使用的对象的引用。