簡體   English   中英

React 組件(react-redux props)不斷使用 React.memo() 重新渲染

[英]React component (react-redux props) keeps rerendering with React.memo()

我正在使用 react、react-redux 和 socket.io 構建一個聊天應用程序。 現在,為了提高應用程序的性能,我將React.memo()添加到我的<Message... />組件中以防止重新渲染。 但是,根據 React Profiler,我的所有消息組件都會在我獲取更多消息時繼續重新渲染。 我的代碼:

room.jsx(消息容器)

import { useSelector, useDispatch } from "react-redux";
import {
  fetchMessagesRequest,
  fetchMessagesSuccess,
  fetchMessagesFailure,
  fetchPageMessagesSuccess,
  fetchPageMessagesFailure,
} from "../../redux/actions";

const Room = ({ match, history }) => {

  const dispatch = useDispatch();
  const socket = useSelector((state) => state.socket);
  const room = useSelector((state) => state.room);
  const user = useSelector((state) => state.user);

    <section className='room__content'>
                {room.messages.length ? (
                  <React.Fragment>
                    {room.messages.map((msg, idx) =>
                      idx + 1 === room.messages.length ? (
                        <Message
                          key={msg._id}
                          reference={lastMessageRef}
                          msg={msg}
                          text={msg.message}
                          file={msg.file ? msg.file : ""}
                          date={msg.creationDate}
                          state={msg.state}
                          deleteMessage={() => deleteMessage(msg._id)}
                          likeMessage={() =>
                            broadcastLike(msg._id, user.data.userID)
                          }
                        />
                      ) : (
                        <Message
                          key={msg._id}
                          msg={msg}
                          text={msg.message}
                          file={msg.file ? msg.file : ""}
                          date={msg.creationDate}
                          state={msg.state}
                          deleteMessage={() => deleteMessage(msg._id)}
                          likeMessage={() =>
                            broadcastLike(msg._id, user.data.userID)
                          }
                        />
                      )
                    )}
                    {preload && <Preloader type='inline' />}
                  </React.Fragment>
                ) : (
                  <Placeholder
                    text='No messages'
                    icon='icon icon--bubbles'
                    type='full'
                  />
                )}
              </section>  
    
...

export default withRouter(Room);

消息.jsx

import React, { useState, useEffect } from "react";
import "./message.scss";

import { LazyLoadImage } from "react-lazy-load-image-component";

/* REDUX */
import { useSelector, useDispatch } from "react-redux";
import { showGallery, showModal, setMessage } from "../../redux/actions";

const Message = ({
  reference,
  msg,
  text,
  file,
  date,
  state,
  deleteMessage,
  likeMessage,
}) => {
  const [loaded, setLoaded] = useState(false);
  const user = useSelector((state) => state.user);
  const dispatch = useDispatch();

  useEffect(() => {
    let mounted = true;

    axios
      .get(...)
      .then()
      .catch()
      .finally(() => setLoaded(true));

    // CLEANUP
    return () => (mounted = false);
  }, []);

  return (
    <React.Fragment>
      {loaded ? (
        <figure
          ref={reference}
          className={`message${author.tag === user.data.tag ? "--author" : ""}`}
        >
            <div className='message__content'>
              <p className='message__content__text'>{text}</p>
            </div>
        </figure>
      ) : (
        ""
      )}
    </React.Fragment>
  );
};

export default React.memo(Message);

roomReducer.js

...

case "FETCH_PAGE_MESSAGES_SUCCESS":
  const messages = [...action.payload.messages, ...state.messages];

  return {
    ...state,
    messages: messages
      .filter(
        (v, i, a) =>
          a.findIndex((t) => JSON.stringify(t) === JSON.stringify(v)) === i
      )
      .sort((a, b) => new Date(b.creationDate) - new Date(a.creationDate)),
    total: action.payload.total,
    error: [],
  };

...

探查器

在此處輸入圖像描述

發生這種情況是因為當您獲取消息時,消息組件的一個或多個依賴項(道具)正在更新。 檢查是否有任何道具取決於 fetch msg 操作。

如果有要傳遞給 Message 組件的函數,請將它們包裝在useCallback鈎子中。

如果問題仍然存在,您可以通過 function 來檢查 React.memo 中的 prevProps 和nextProps

 const isEqual = (prevProps, nextProps) => {}
 React.memo(Message, isEqual)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM