我在我的应用程序中使用 React 和 Redux Toolkit 进行状态管理,该应用程序具有嵌套的组件结构。假设我有三个主要组件:一个主包装组件、一个项目组件和一个子项目组件。子项组件也可以有多个嵌套子组件。 item 和子 item 组件都使用 useState、useEffect 和 useSelector 来管理和检索 Redux 中的数据。
所有数据都以对象数组的形式存储在 Redux 中,每个对象包含一个 level 字段(表示嵌套级别)和一个 prevId 字段(表示父数据)。我循环访问主包装器组件中的 Redux 数据,以使用 item 组件显示它。在项目组件中,我为任何直接子项目调用子项目组件(基于 prevId)。这种结构有点类似于组件的链表。
我面临的问题是,当我切换到编辑模式时,每个项目或子项目都会渲染多次(我已经使用 console.count 验证了这一点以跟踪重新渲染的次数),即使我没有尚未进行任何更改。
有人有类似问题的解决方案或指导吗?
我已经为组件内部可能的值实现了 useMemo,为组件本身实现了 React.memo,以防止不必要的重新渲染,但它似乎没有任何效果。
包装组件
const WrapperComponent = () => {
const ItemDataRedux = useSelector(selectItemDataRedux);
const ItemListData = useDebounce(ItemDataRedux, 450);
const memoizedItemData = useMemo(() => {
return ItemListData?.filter((obj: Item) => obj.level === 1);
}, [ItemListData]);
return (
<div>
{memoizedItemData?.map((item: Item, index: number) => (
<ItemComponent
key={`list-of-step-${item.idid}`}
idElement={item.idElement}
typeElement={item.type}
prevId={item.prevId!}
level={1}
name={item.name ?? ""}
orderNumber={item.orderNumber}
nextLogic={item.nextLogic}
// in item component, i name it as nextLogicServer from props
listItemChild={item?.listItemChild ?? []}
/>
))}
</div>
);
};
export default WrapperComponent;
项目组件
const ItemDataRedux = useSelector(selectItemDataRedux);
const [nextLogic, setNextLogic] = useState<nextLogicType>({
GoNextLogic: nextLogicServer?.GoNextLogic ?? null,
});
const [nameElement, setNameElement] = useState<string>(name || "");
useEffect(() => {
// update the local nextLogic where parent changes
setNextLogic({
...nextLogic,
GoNextLogic: nextLogicServer?.GoNextLogic ?? null,
});
}, [nextLogicServer?.GoNextLogic]);
useEffect(() => {
const SaveData = () => {
// update the data in redux selectItemDataRedux by idElement
dispatch(
updateElementByIdElement({
idElement,
nextLogic,
})
);
};
// v1 directly update
// SaveData();
// v2 delay by 0.2 second then update
const timeoutId = setTimeout(() => {
SaveData();
}, 200);
return () => {
clearTimeout(timeoutId);
};
}, [nextLogic, idElement]);
updateElementByIdElement 用于更新
const ItemDataRedux = useSelector(selectItemDataRedux);
的父数据
看你在 useeffect 依赖中使用
idElement
并且你在其中映射一个数据,如果你传递了 100 个数据idElement
它可以重新渲染 useeffect 并且它对应的函数 100 次,因此它可以做出反应显示你是渲染错误或项目崩溃。