我对此做了一些研究,普遍的共识似乎是利用 useMemo
和 memo
React 组件,但我没有任何运气。
我有一个父 React 组件 (TypeScript),它还呈现一个自定义子组件,该子组件本质上创建一个 HTML select
标记。这一切都有效。但是,使用 TanStack 查询定期刷新父组件以显示新获取的信息。这种情况大约每秒发生一次。如果用户正在选择下拉列表中的项目,则发生这种情况时下拉列表将关闭并必须再次打开。不用说这很烦人。
我尝试了以下方法,但没有成功:
import { useState, useEffect, useRef, memo, useMemo } from "react";
function LogData(props: Props) {
const [selectedUrl, setSelectedUrl] = useState<number>(0); // Tracks UI dropdown selection
const theUrl = useMemo(
() => ({ selectedUrl, setSelectedUrl }),
[selectedUrl]
);
// This periodically executes the TanStack query which causes this component to rerender
const { status, error, data, fetchStatus } = usePeriodicQuery(
logUrl[selectedUrl],
updateIntervalMs,
"myQuery",
isEnabled.current
);
...additional code to parse the data...
const MemoizedLogSelector = memo(LogSelector);
return (
<MemoizedLogSelector selectedUrlMemo={theUrl} />
<TableContainer component={Paper}>
...table data code...
</TableContainer>
);
function LogSelector(props: {
selectedUrlMemo: {
selectedUrl: number,
setSelectedUrl: React.Dispatch<React.SetStateAction<number>>,
};
}) {
console.warn(">>> LogSelector is rendering..."); // This is printing on every parent rerender
return (
<TextSelectInput
label="Log Select:"
labelFontSize="body1"
labelPlacement="row"
onChange={(value: number) => props.selectedUrlMemo.setSelectedUrl(value)}
onClear={() => {}}
options={[
{
label: "Message1",
value: 0,
},
{
label: "Message2",
value: 1,
},
{
label: "Message3",
value: 2,
},
]}
value={props.selectedUrlMemo.selectedUrl}
/>
);
}
这段代码有问题吗?或者有其他方法可以完成我正在寻找的事情吗?
最佳答案
const MemoizedLogSelector = memo(LogSelector);
问题是这行代码位于 LogData 的内部。因此,每次 logData 渲染时,您都会创建一个全新的 MemoizedLogSelector 组件。它可能具有与前一个相同的功能,但它是一个新的函数引用,因此它看起来像是一个不同的组件类型来使用react。因此,react 必须卸载旧的并安装新的,这会重置任何内部状态。
组件只能定义一次,因此请将代码行移到 LogData 之外:
const MemoizedLogSelector = memo(LogSelector);
function LogData(props: Props) {
// ...
return (
<MemoizedLogSelector selectedUrlMemo={theUrl} />
<TableContainer component={Paper}>
...table data code...
</TableContainer>
);
}
关于javascript - 刷新父组件时,防止子 React 组件中的下拉菜单关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77191425/