我有这个应用程序,我在其中加载页面加载时的大量数据,然后使用react-tables呈现表。每行都有一个“合规性”列,其中包含状态标签,用于说明是否符合要求。此列还包含一个按钮,按下该按钮可更新状态(queuedPortRecommendations
),并为其提供建议的兼容值。
该表需要很长时间才能呈现,就像它在1400行左右时所期望的那样。但是我不知道为什么为什么在调用addQueuedChange
函数时会重新渲染?
我尝试从addQueuedChange
的deps数组中删除useMemo
,但是没有将字符串添加到该数组中,而是将其替换了。
我知道很难得出一个直接的答案,但是任何提示或想法都将不胜感激。
const App = () => {
const [data, setData] = useState<Port[]>([]);
const [queuedPortRecommendations, setQueuedPortRecommendations] = useState<string[]>([]);
useEffect(() => {
const doFetch = async () => {
const response = await fetch(`${BACKEND_BASE}/api/v1/ports?allData=false`);
const body: BackendResponse = await response.json()
const { ports, portStats } = body.data;
setData(ports);
}
doFetch()
}, [data]);
const addQueuedChange = (portRecommendation: string) => {
setQueuedPortRecommendations([...queuedPortRecommendations, portRecommendation]);
};
const columns = useMemo(
() => [
{
Header: 'Device name',
accessor: 'device.hostname'
},
{
Header: 'Compliance checks',
accessor: (port: Port) => {
return (
<PortDescriptionRecommendation
key={`${port.device}-${port.ifName}-port-recommendation`}
port={port}
addQueuedChange={addQueuedChange}
/>
);
},
}
],
[addQueuedChange]
)
return <TableContainer columns={columns} data={data} />;
const PortDescriptionRecommendation = ({ port, addQueuedChange }: {port: Port, addQueuedChange: (portRecommendation: string) => void }) => {
const {remoteHostName, remotePort, tag, type} = port.portRecommendation;
const remotePortDescription = remotePort ? ` (${remotePort})` : '';
const handleAddToQueueButtonClicks = () => {
addQueuedChange(portConfig);
}
let portConfig = `
conf t
interface ${port.ifName}
description ${tag}${remoteHostName || ''}${remotePortDescription}
end
wr mem`;
return (
<button data-tip={portConfig} className={'btn btn-sm btn-info'} onClick={handleAddToQueueButtonClicks}>
Add recommendation to list
</button>
);
}
答案 0 :(得分:1)
您应使用useCallback
来避免重新渲染,每次更新应用程序状态时,都会创建一个新的addQueuedChange
实例。这就是为什么。而且您不必将其添加到依赖关系数组中。
答案 1 :(得分:1)
首先,您要将useCallback
添加到addQueuedChange
,这样就不会在每个渲染上创建新的columns
。
尽管它可能无法完全解决问题:
当App
组件重新呈现时。 TableContainer
也被重新渲染。这是默认的React行为:更新parent时,它将重新渲染所有子代。要更改此行为,您应该使用React.memo。
通常,在处理大表时,您想使用React.memo
。根据我的经验,我通常也会记住表格的行。
确保addQueuedChange
不依赖于portRecommendation
const addQueuedChange = useCallback(
(portRecommendation: string) => {
setQueuedPortRecommendations((prevPortRecommendation) => [
...prevPortRecommendation,
portRecommendation,
]);
},
[setQueuedPortRecommendations]
);