React (Next) не будет повторно отображаться после изменения состояния избыточности (да, состояние возвращается как новый объект)

У меня возникла проблема с повторный рендеринг после изменения состояния в моем приложении 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;

Ваш магазин обновляется правильно? Вы проверили с помощью веб-инструментов Redux?

coglialoro 18.03.2022 23:37

@coglialoro да, я отлично вижу новые данные, используя веб-инструменты redux, и, как я уже упоминал @kodamace, если я запускаю повторную визуализацию (набрав форму, которая использует useState, следовательно, повторную визуализацию), будет отображаться обновленный список

gNazi 19.03.2022 05:05
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

useSelector требуется новый объект с новой ссылкой из объекта, который вы ему передаете, чтобы вызвать повторный рендеринг

То, что вы делаете с return {...state}, - это просто создание нового объекта для родительского объекта, но не вложенного объекта useSelector, который используется в вашем случае:

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

Итак, вы должны вернуть все состояние как новый объект С новым объектом state.chat[roomId].messages

Другими словами, ссылки на корневой объект и тот, который используется, должны быть изменены.

Я думал об этом, но мне сказали, что redux проверяет корневой объект на предмет повторного рендеринга, поэтому я не стал его тестировать. Я попробую это как можно скорее, скрестив пальцы :D

gNazi 20.03.2022 02:21

Другие вопросы по теме