From 4d2e6de0754e308ea6aaa4f37d4d31d67a0b1945 Mon Sep 17 00:00:00 2001 From: Jason Morse Date: Wed, 28 Jan 2026 09:09:09 -0800 Subject: [PATCH 1/2] ensure useRef always has a parameter --- .../src/TestComponents/FocusZone/FocusZoneE2ETest.tsx | 2 +- .../src/TestComponents/FocusZone/FocusZoneTest.tsx | 4 ++-- packages/components/Menu/src/Menu/useMenu.android.ts | 2 +- packages/components/Menu/src/Menu/useMenu.ts | 3 ++- packages/components/Menu/src/MenuList/useMenuList.ts | 2 +- packages/experimental/Dropdown/src/Dropdown/Dropdown.tsx | 2 +- packages/utils/interactive-hooks/src/useConst.ts | 4 ++-- packages/utils/interactive-hooks/src/useViewCommandFocus.ts | 2 +- 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/tester-core/src/TestComponents/FocusZone/FocusZoneE2ETest.tsx b/apps/tester-core/src/TestComponents/FocusZone/FocusZoneE2ETest.tsx index 63ee5ef403..a32b89f44c 100644 --- a/apps/tester-core/src/TestComponents/FocusZone/FocusZoneE2ETest.tsx +++ b/apps/tester-core/src/TestComponents/FocusZone/FocusZoneE2ETest.tsx @@ -29,7 +29,7 @@ export const FocusZoneTabNavigations: FocusZoneTabNavigation[] = ['None', 'Navig // Buttons by default focus on click on Win32, but they don't on the Mac, so place focus explicitly for convenience function useFocusOnClickForMac(): Partial { - const componentRef = React.useRef(); + const componentRef = React.useRef(null); const onClick = React.useCallback(() => componentRef.current?.focus(), [componentRef]); return Platform.OS === 'macos' ? { componentRef, onClick } : {}; } diff --git a/apps/tester-core/src/TestComponents/FocusZone/FocusZoneTest.tsx b/apps/tester-core/src/TestComponents/FocusZone/FocusZoneTest.tsx index 2cc2cb1004..112236c402 100644 --- a/apps/tester-core/src/TestComponents/FocusZone/FocusZoneTest.tsx +++ b/apps/tester-core/src/TestComponents/FocusZone/FocusZoneTest.tsx @@ -115,14 +115,14 @@ const FocusZoneTabNavigationComponent: React.FunctionComponent = () => { }; const TinyBox = () => { - const ref = React.useRef(); + const ref = React.useRef(null); const onPress = useOnPressWithFocus(ref, null); return ; }; const WideBox = () => { - const ref = React.useRef(); + const ref = React.useRef(null); const onPress = useOnPressWithFocus(ref, null); return ; diff --git a/packages/components/Menu/src/Menu/useMenu.android.ts b/packages/components/Menu/src/Menu/useMenu.android.ts index f098fde8ab..0694496c08 100644 --- a/packages/components/Menu/src/Menu/useMenu.android.ts +++ b/packages/components/Menu/src/Menu/useMenu.android.ts @@ -30,7 +30,7 @@ export const useMenu = (props: MenuProps): MenuState => { * State , Ref and Context Values for Menu Container and Anchor */ - const triggerRef = React.useRef(); + const triggerRef = React.useRef(null); const context = useMenuContext(); const isSubmenu = context.triggerRef !== null; const isOpenControlled = typeof props.open !== 'undefined'; diff --git a/packages/components/Menu/src/Menu/useMenu.ts b/packages/components/Menu/src/Menu/useMenu.ts index f907280ec0..aa81b9d27d 100644 --- a/packages/components/Menu/src/Menu/useMenu.ts +++ b/packages/components/Menu/src/Menu/useMenu.ts @@ -1,4 +1,5 @@ import React from 'react'; +import type { View } from 'react-native'; import { Platform } from 'react-native'; import type { InteractionEvent } from '@fluentui-react-native/interactive-hooks'; @@ -14,7 +15,7 @@ import { useMenuContext } from '../context/menuContext'; const delayOpen = 150; export const useMenu = (props: MenuProps): MenuState => { - const triggerRef = React.useRef(); + const triggerRef = React.useRef(null); const context = useMenuContext(); const isSubmenu = context.triggerRef !== null; const isOpenControlled = typeof props.open !== 'undefined'; diff --git a/packages/components/Menu/src/MenuList/useMenuList.ts b/packages/components/Menu/src/MenuList/useMenuList.ts index 087fea98e3..93f8a8d8cb 100644 --- a/packages/components/Menu/src/MenuList/useMenuList.ts +++ b/packages/components/Menu/src/MenuList/useMenuList.ts @@ -164,7 +164,7 @@ export const useMenuList = (_props: MenuListProps): MenuListState => { }); // focus management - const focusZoneRef = React.useRef(); + const focusZoneRef = React.useRef(null); const setFocusZoneFocus = () => { focusZoneRef?.current?.focus(); }; diff --git a/packages/experimental/Dropdown/src/Dropdown/Dropdown.tsx b/packages/experimental/Dropdown/src/Dropdown/Dropdown.tsx index 99b0d8986c..5ab709e6b1 100644 --- a/packages/experimental/Dropdown/src/Dropdown/Dropdown.tsx +++ b/packages/experimental/Dropdown/src/Dropdown/Dropdown.tsx @@ -20,7 +20,7 @@ const Dropdown = compressible((props: DropdownPro const onButtonClick = React.useCallback(() => { setOpen(!isOpen); }, [isOpen, setOpen]); - const defaultRef = React.useRef(); + const defaultRef = React.useRef(null); const buttonProps: ButtonProps = React.useMemo( () => ({ diff --git a/packages/utils/interactive-hooks/src/useConst.ts b/packages/utils/interactive-hooks/src/useConst.ts index e667b9af0e..0be8f0a031 100644 --- a/packages/utils/interactive-hooks/src/useConst.ts +++ b/packages/utils/interactive-hooks/src/useConst.ts @@ -17,8 +17,8 @@ export function useConst(initialValue: T | FunctionToValue): T { // Use useRef to store the value because it's the least expensive built-in hook that works here // (we could also use `const [value] = React.useState(initialValue)` but that's more expensive // internally due to reducer handling which we don't need) - const ref = React.useRef<{ value: T }>(); - if (ref.current === undefined) { + const ref = React.useRef<{ value: T }>(null); + if (ref.current == null) { // Box the value in an object so we can tell if it's initialized even if the initializer // returns/is undefined ref.current = { diff --git a/packages/utils/interactive-hooks/src/useViewCommandFocus.ts b/packages/utils/interactive-hooks/src/useViewCommandFocus.ts index a2aa9d6eac..f15a3f46de 100644 --- a/packages/utils/interactive-hooks/src/useViewCommandFocus.ts +++ b/packages/utils/interactive-hooks/src/useViewCommandFocus.ts @@ -17,7 +17,7 @@ export function useViewCommandFocus( /** * Set up the forwarding ref to enable adding the focus method. */ - const focusRef = React.useRef(); + const focusRef = React.useRef(null); const _setNativeRef = setAndForwardRef({ getForwardedRef: () => forwardedRef, From ff359f4a0f163eade3338c3fc887376c9efb7db1 Mon Sep 17 00:00:00 2001 From: Jason Morse Date: Wed, 28 Jan 2026 09:10:09 -0800 Subject: [PATCH 2/2] Change files --- ...tive-dropdown-a2d16a93-ba43-4564-a943-b953e2f37bdc.json | 7 +++++++ ...ractive-hooks-c5f83930-eeb6-437e-be1f-70570a80673c.json | 7 +++++++ ...t-native-menu-65d7be21-127b-48d4-b3d4-c5faf40d7908.json | 7 +++++++ ...e-tester-core-e0aba239-aa77-4f11-abfc-476ec7035d37.json | 7 +++++++ 4 files changed, 28 insertions(+) create mode 100644 change/@fluentui-react-native-dropdown-a2d16a93-ba43-4564-a943-b953e2f37bdc.json create mode 100644 change/@fluentui-react-native-interactive-hooks-c5f83930-eeb6-437e-be1f-70570a80673c.json create mode 100644 change/@fluentui-react-native-menu-65d7be21-127b-48d4-b3d4-c5faf40d7908.json create mode 100644 change/@fluentui-react-native-tester-core-e0aba239-aa77-4f11-abfc-476ec7035d37.json diff --git a/change/@fluentui-react-native-dropdown-a2d16a93-ba43-4564-a943-b953e2f37bdc.json b/change/@fluentui-react-native-dropdown-a2d16a93-ba43-4564-a943-b953e2f37bdc.json new file mode 100644 index 0000000000..a4110b4198 --- /dev/null +++ b/change/@fluentui-react-native-dropdown-a2d16a93-ba43-4564-a943-b953e2f37bdc.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "ensure useRef always has a parameter", + "packageName": "@fluentui-react-native/dropdown", + "email": "jasonmo@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-native-interactive-hooks-c5f83930-eeb6-437e-be1f-70570a80673c.json b/change/@fluentui-react-native-interactive-hooks-c5f83930-eeb6-437e-be1f-70570a80673c.json new file mode 100644 index 0000000000..3e6327ac2a --- /dev/null +++ b/change/@fluentui-react-native-interactive-hooks-c5f83930-eeb6-437e-be1f-70570a80673c.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "ensure useRef always has a parameter", + "packageName": "@fluentui-react-native/interactive-hooks", + "email": "jasonmo@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-native-menu-65d7be21-127b-48d4-b3d4-c5faf40d7908.json b/change/@fluentui-react-native-menu-65d7be21-127b-48d4-b3d4-c5faf40d7908.json new file mode 100644 index 0000000000..2ec3d3af37 --- /dev/null +++ b/change/@fluentui-react-native-menu-65d7be21-127b-48d4-b3d4-c5faf40d7908.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "ensure useRef always has a parameter", + "packageName": "@fluentui-react-native/menu", + "email": "jasonmo@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-native-tester-core-e0aba239-aa77-4f11-abfc-476ec7035d37.json b/change/@fluentui-react-native-tester-core-e0aba239-aa77-4f11-abfc-476ec7035d37.json new file mode 100644 index 0000000000..2bf00e50dd --- /dev/null +++ b/change/@fluentui-react-native-tester-core-e0aba239-aa77-4f11-abfc-476ec7035d37.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "ensure useRef always has a parameter", + "packageName": "@fluentui-react-native/tester-core", + "email": "jasonmo@microsoft.com", + "dependentChangeType": "patch" +}