У меня возникла проблема с повторный рендеринг после изменения состояния в моем приложении NextJS.
Функция sendMessageForm
запускает избыточное действие 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.info("***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;
@coglialoro да, я отлично вижу новые данные, используя веб-инструменты redux, и, как я уже упоминал @kodamace, если я запускаю повторную визуализацию (набрав форму, которая использует useState
, следовательно, повторную визуализацию), будет отображаться обновленный список
useSelector
требуется новый объект с новой ссылкой из объекта, который вы ему передаете, чтобы вызвать повторный рендеринг
То, что вы делаете с return {...state}
, - это просто создание нового объекта для родительского объекта, но не вложенного объекта useSelector
, который используется в вашем случае:
const messages = useSelector((state)=> state.chat[roomId].messages)
Итак, вы должны вернуть все состояние как новый объект С новым объектом state.chat[roomId].messages
Другими словами, ссылки на корневой объект и тот, который используется, должны быть изменены.
Я думал об этом, но мне сказали, что redux проверяет корневой объект на предмет повторного рендеринга, поэтому я не стал его тестировать. Я попробую это как можно скорее, скрестив пальцы :D
Ваш магазин обновляется правильно? Вы проверили с помощью веб-инструментов Redux?