diff --git a/package.json b/package.json index fc9dfb54..85bd150d 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "dependencies": { "@rc-component/motion": "^1.1.4", "@rc-component/trigger": "^3.0.0", - "@rc-component/util": "^1.0.0", + "@rc-component/util": "^1.3.0", "classnames": "2.x", "rc-overflow": "^1.3.1" }, diff --git a/src/Menu.tsx b/src/Menu.tsx index 9c08850e..2bca5add 100644 --- a/src/Menu.tsx +++ b/src/Menu.tsx @@ -1,7 +1,8 @@ import classNames from 'classnames'; import type { CSSMotionProps } from '@rc-component/motion'; import Overflow from 'rc-overflow'; -import useMergedState from '@rc-component/util/lib/hooks/useMergedState'; +import useControlledState from '@rc-component/util/lib/hooks/useControlledState'; +import useId from '@rc-component/util/lib/hooks/useId'; import isEqual from '@rc-component/util/lib/isEqual'; import warning from '@rc-component/util/lib/warning'; import * as React from 'react'; @@ -14,7 +15,6 @@ import PrivateContext from './context/PrivateContext'; import { getFocusableElements, refreshElements, useAccessibility } from './hooks/useAccessibility'; import useKeyRecords, { OVERFLOW_KEY } from './hooks/useKeyRecords'; import useMemoCallback from './hooks/useMemoCallback'; -import useUUID from './hooks/useUUID'; import type { BuiltinPlacements, Components, @@ -260,7 +260,7 @@ const Menu = React.forwardRef((props, ref) => { const containerRef = React.useRef(); - const uuid = useUUID(id); + const uuid = useId(id ? `rc-menu-uuid-${id}` : 'rc-menu-uuid'); const isRtl = direction === 'rtl'; @@ -273,10 +273,8 @@ const Menu = React.forwardRef((props, ref) => { } // ========================= Open ========================= - const [mergedOpenKeys, setMergedOpenKeys] = useMergedState(defaultOpenKeys, { - value: openKeys, - postState: keys => keys || EMPTY_LIST, - }); + const [innerOpenKeys, setMergedOpenKeys] = useControlledState(defaultOpenKeys, openKeys); + const mergedOpenKeys = innerOpenKeys || EMPTY_LIST; // React 18 will merge mouse event which means we open key will not sync // ref: https://github.com/ant-design/ant-design/issues/38818 @@ -376,11 +374,9 @@ const Menu = React.forwardRef((props, ref) => { }, [lastVisibleIndex, allVisible]); // ======================== Active ======================== - const [mergedActiveKey, setMergedActiveKey] = useMergedState( + const [mergedActiveKey, setMergedActiveKey] = useControlledState( activeKey || ((defaultActiveFirst && childList[0]?.key) as string), - { - value: activeKey, - }, + activeKey, ); const onActive = useMemoCallback((key: string) => { @@ -423,22 +419,21 @@ const Menu = React.forwardRef((props, ref) => { // ======================== Select ======================== // >>>>> Select keys - const [mergedSelectKeys, setMergedSelectKeys] = useMergedState(defaultSelectedKeys || [], { - value: selectedKeys, - - // Legacy convert key to array - postState: keys => { - if (Array.isArray(keys)) { - return keys; - } + const [internalSelectKeys, setMergedSelectKeys] = useControlledState( + defaultSelectedKeys || [], + selectedKeys, + ); + const mergedSelectKeys = React.useMemo(() => { + if (Array.isArray(internalSelectKeys)) { + return internalSelectKeys; + } - if (keys === null || keys === undefined) { - return EMPTY_LIST; - } + if (internalSelectKeys === null || internalSelectKeys === undefined) { + return EMPTY_LIST; + } - return [keys]; - }, - }); + return [internalSelectKeys]; + }, [internalSelectKeys]); // >>>>> Trigger select const triggerSelection = (info: MenuInfo) => { diff --git a/src/context/IdContext.ts b/src/context/IdContext.ts index ec16a790..8190bdec 100644 --- a/src/context/IdContext.ts +++ b/src/context/IdContext.ts @@ -3,9 +3,6 @@ import * as React from 'react'; export const IdContext = React.createContext(null); export function getMenuId(uuid: string, eventKey: string) { - if (uuid === undefined) { - return null; - } return `${uuid}-${eventKey}`; } diff --git a/src/hooks/useUUID.ts b/src/hooks/useUUID.ts deleted file mode 100644 index a939de82..00000000 --- a/src/hooks/useUUID.ts +++ /dev/null @@ -1,18 +0,0 @@ -import * as React from 'react'; -import useMergedState from '@rc-component/util/lib/hooks/useMergedState'; - -const uniquePrefix = Math.random().toFixed(5).toString().slice(2); - -let internalId = 0; - -export default function useUUID(id?: string) { - const [uuid, setUUID] = useMergedState(id, { value: id }); - - React.useEffect(() => { - internalId += 1; - const newId = process.env.NODE_ENV === 'test' ? 'test' : `${uniquePrefix}-${internalId}`; - setUUID(`rc-menu-uuid-${newId}`); - }, []); - - return uuid; -} diff --git a/tests/__snapshots__/Keyboard.spec.tsx.snap b/tests/__snapshots__/Keyboard.spec.tsx.snap index 26f47c1d..1230f1be 100644 --- a/tests/__snapshots__/Keyboard.spec.tsx.snap +++ b/tests/__snapshots__/Keyboard.spec.tsx.snap @@ -13,11 +13,11 @@ HTMLCollection [ role="none" >