0

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: [],
  };

...

プロファイラ

ここに画像の説明を入力

4

1 に答える 1