如何在反应中限制经常重新渲染的组件
Posted
技术标签:
【中文标题】如何在反应中限制经常重新渲染的组件【英文标题】:How to throttle often re-rendered component in react 【发布时间】:2021-11-28 08:32:27 【问题描述】:我想限制连接到 WS 并经常获取数据的渲染组件,这会导致它经常重新渲染。
我有useMemo
钩子的解决方案,但我不确定useMemo
是为此类事情设计的。
当然,data
的每次更新都会导致重新渲染,因为useState
就是这样工作的,我必须更新这个data
状态。
您是否有一些建议或想法如何限制<DataVisualizator />
组件的重新渲染?
useInterval hook
import useEffect, useRef from "react";
export const useInterval = (callback: () => void, delay: number) =>
const savedCallback = useRef<() => void>();
useEffect(() =>
savedCallback.current = callback;
, [callback]);
useEffect(() =>
function tick()
if (savedCallback.current)
savedCallback.current();
if (delay !== null)
let id = setInterval(tick, delay);
return () => clearInterval(id);
, [delay]);
;
以及接收数据并应限制其子级的组件
import useEffect, useMemo, useState from "react";
import useWebSocket from "react-use-websocket";
import useInterval from "../Hooks";
export const WebSockets = () =>
const SOCKET_URL = "wss://someWS";
//data will be kind of Dictionary .eg "key1": val, "anotherkey: valOther
const [data, setData] = useState();
const webSocketOptions =
shouldReconnect: () => true,
retryOnError: true,
reconnectInterval: 3000,
reconnectAttempts: 5,
onError: (e) => console.log(e),
;
const sendMessage, lastMessage = useWebSocket(
SOCKET_URL,
webSocketOptions
);
const handleData = (message: RequestData, data: OrderBookData) =>
// lot of operations to deepClone state and set new with new Data
setData(clonedData);
;
useEffect(() =>
lastMessage && handleData(JSON.parse(lastMessage.data), data);
// eslint-disable-next-line react-hooks/exhaustive-deps
, [lastMessage]);
const [tickThrottle, setTickThrottle] = useState(false);
useInterval(() =>
setTickThrottle(!tickThrottle);
, 700);
//Throttling with useMemo hook
const throttledDataVisdsualizator = useMemo(
() => <DataVisualizator dataToVisualize=data />,
// eslint-disable-next-line react-hooks/exhaustive-deps
[tickThrottle]
);
return (
<>
throttledDataVisdsualizator
</>
);
;
【问题讨论】:
【参考方案1】:用useMemo
钩子解决
const [tickThrottle, setTickThrottle] = useState(false);
useInterval(() =>
setTickThrottle(!tickThrottle);
, 700);
//Throttling with useMemo hook
const throttledDataVisdsualizator = useMemo(
() => <DataVisualizator dataToVisualize=data />,
// eslint-disable-next-line react-hooks/exhaustive-deps
[tickThrottle]
);
return (
<>
throttledDataVisdsualizator
</>
);
【讨论】:
这只会在data
始终是一个新对象的情况下进行限制;如果data
被内部修改,这些更改将被渲染。
@AKX 是的,数据将始终是新对象,在handleData
内部我对当前状态进行深度克隆并将修改后的深度克隆设置为新对象,因此数据始终是新对象以上是关于如何在反应中限制经常重新渲染的组件的主要内容,如果未能解决你的问题,请参考以下文章