From c098a173e9024ea9ca91d66323f81379298ed637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=B1=AA?= <1844749591@qq.com> Date: Wed, 25 Dec 2024 02:06:07 +0800 Subject: [PATCH 1/3] fix: force update to keep disable state work --- src/OptionList.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/OptionList.tsx b/src/OptionList.tsx index d69aec40..212454b5 100644 --- a/src/OptionList.tsx +++ b/src/OptionList.tsx @@ -162,10 +162,18 @@ const OptionList: React.ForwardRefRenderFunction = (_, // ========================= Disabled ========================= const disabledCacheRef = React.useRef>(new Map()); - // Clear cache if `leftMaxCount` changed + // Force update is needed since clearing cache alone doesn't trigger + // a recalculation of node disabled states + const [, setForceUpdate] = React.useState({}); + + // When leftMaxCount changes, we need to: + // 1. Clear the disabled state cache + // 2. Trigger a re-render to recalculate all node disabled states + // This ensures parent nodes are properly disabled when max count is reached React.useEffect(() => { if (leftMaxCount) { disabledCacheRef.current.clear(); + setForceUpdate({}); } }, [leftMaxCount]); From a5b1e9b95a3c035f7a49ec40f57e54c2a7b69795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=B1=AA?= <1844749591@qq.com> Date: Wed, 25 Dec 2024 11:08:16 +0800 Subject: [PATCH 2/3] refactor: replace disabled ref cache with state --- src/OptionList.tsx | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/OptionList.tsx b/src/OptionList.tsx index 212454b5..e876ae53 100644 --- a/src/OptionList.tsx +++ b/src/OptionList.tsx @@ -160,26 +160,18 @@ const OptionList: React.ForwardRefRenderFunction = (_, }, [searchValue]); // ========================= Disabled ========================= - const disabledCacheRef = React.useRef>(new Map()); + // Cache disabled states in React state to ensure re-render when cache updates + const [disabledCache, setDisabledCache] = React.useState>(new Map()); - // Force update is needed since clearing cache alone doesn't trigger - // a recalculation of node disabled states - const [, setForceUpdate] = React.useState({}); - - // When leftMaxCount changes, we need to: - // 1. Clear the disabled state cache - // 2. Trigger a re-render to recalculate all node disabled states - // This ensures parent nodes are properly disabled when max count is reached React.useEffect(() => { if (leftMaxCount) { - disabledCacheRef.current.clear(); - setForceUpdate({}); + setDisabledCache(new Map()); } }, [leftMaxCount]); function getDisabledWithCache(node: DataNode) { const value = node[fieldNames.value]; - if (!disabledCacheRef.current.has(value)) { + if (!disabledCache.has(value)) { const entity = valueEntities.get(value); const isLeaf = (entity.children || []).length === 0; @@ -192,12 +184,16 @@ const OptionList: React.ForwardRefRenderFunction = (_, ); const checkableChildrenCount = checkableChildren.length; - disabledCacheRef.current.set(value, checkableChildrenCount > leftMaxCount); + const newCache = new Map(disabledCache); + newCache.set(value, checkableChildrenCount > leftMaxCount); + setDisabledCache(newCache); } else { - disabledCacheRef.current.set(value, false); + const newCache = new Map(disabledCache); + newCache.set(value, false); + setDisabledCache(newCache); } } - return disabledCacheRef.current.get(value); + return disabledCache.get(value); } const nodeDisabled = useEvent((node: DataNode) => { From 4f4b124a3f0fbeed647e628bd9b565aaf8ae5e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=B1=AA?= <1844749591@qq.com> Date: Wed, 25 Dec 2024 11:30:19 +0800 Subject: [PATCH 3/3] perf: remove unnecessary setState and init map --- src/OptionList.tsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/OptionList.tsx b/src/OptionList.tsx index e876ae53..5b53047e 100644 --- a/src/OptionList.tsx +++ b/src/OptionList.tsx @@ -161,7 +161,7 @@ const OptionList: React.ForwardRefRenderFunction = (_, // ========================= Disabled ========================= // Cache disabled states in React state to ensure re-render when cache updates - const [disabledCache, setDisabledCache] = React.useState>(new Map()); + const [disabledCache, setDisabledCache] = React.useState>(() => new Map()); React.useEffect(() => { if (leftMaxCount) { @@ -184,13 +184,9 @@ const OptionList: React.ForwardRefRenderFunction = (_, ); const checkableChildrenCount = checkableChildren.length; - const newCache = new Map(disabledCache); - newCache.set(value, checkableChildrenCount > leftMaxCount); - setDisabledCache(newCache); + disabledCache.set(value, checkableChildrenCount > leftMaxCount); } else { - const newCache = new Map(disabledCache); - newCache.set(value, false); - setDisabledCache(newCache); + disabledCache.set(value, false); } } return disabledCache.get(value);