[英]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.