From 1fba21c10860cadf34691460613c3d683ced86e9 Mon Sep 17 00:00:00 2001 From: elevatebart Date: Thu, 30 Nov 2023 17:01:42 +0100 Subject: [PATCH] fix dependency react footgun --- components/DocMenu/react/DocMenuReact.cy.tsx | 2 +- components/DocMenu/react/_DocGroup.tsx | 50 +++++++++++++++----- components/DocMenu/react/_DocLink.tsx | 4 +- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/components/DocMenu/react/DocMenuReact.cy.tsx b/components/DocMenu/react/DocMenuReact.cy.tsx index f726d8fe8..3281602a1 100644 --- a/components/DocMenu/react/DocMenuReact.cy.tsx +++ b/components/DocMenu/react/DocMenuReact.cy.tsx @@ -25,7 +25,7 @@ describe('', () => { = ({ ) React.useEffect(() => { - setHeight?.(open ? itemsHeights.reduce((a, b) => a + b, 1) : 1) - }, [itemsHeights, open, setHeight]) + // if this group contains other groups, ignore this effect + // it will be triggered by a leaf and trickle up + if (group.items.some((item) => 'items' in item)) { + return + } + + const newHeight = open ? itemsHeights.reduce((a, b) => a + b, 1) : 1 + + setHeight?.(newHeight) + }, [itemsHeights, open, setHeight, group.items, group.label]) const [activeTop, setActiveTop] = React.useState(0) @@ -44,13 +52,16 @@ export const DocGroup: React.FC = ({ setOpen(open) } - function onSetHeight(index: number, height: number) { - setItemsHeights((prev) => { - const newHeights = [...prev] - newHeights[index] = height - return newHeights - }) - } + const onSetHeightCallback = React.useCallback( + (index: number, height: number) => { + setItemsHeights((prev) => { + const newHeights = [...prev] + newHeights[index] = height + return newHeights + }) + }, + [setItemsHeights], + ) const Head = collapsible ? 'button' : group.href ? 'a' : 'div' @@ -99,11 +110,12 @@ export const DocGroup: React.FC = ({ {group.items.map((item, index) => 'items' in item ? (
  • - onSetHeight(index, height)} + setHeight={onSetHeightCallback} collapsible={collapsible} + index={index} />
  • ) : ( @@ -120,3 +132,19 @@ export const DocGroup: React.FC = ({ ) } + +const DocGroupWithIndex: React.FC< + Omit & { + index: number + setHeight: (index: number, height: number) => void + } +> = ({ setHeight, index, ...props }) => { + const onSetHeight = React.useCallback( + (height: number) => { + setHeight(index, height) + }, + [index, setHeight], + ) + + return +} diff --git a/components/DocMenu/react/_DocLink.tsx b/components/DocMenu/react/_DocLink.tsx index 107fdc58d..77377d884 100644 --- a/components/DocMenu/react/_DocLink.tsx +++ b/components/DocMenu/react/_DocLink.tsx @@ -23,9 +23,7 @@ export const DocLink: React.FC = ({ if (item.active) { onActive?.(activeLIRef?.current?.offsetTop || 0) } - // supposed to happen only on mount - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + }, [onActive, item.active]) return (