diff --git a/packages/react-native-web/src/exports/Picker/index.js b/packages/react-native-web/src/exports/Picker/index.js index a3069d336..5bf955e2c 100644 --- a/packages/react-native-web/src/exports/Picker/index.js +++ b/packages/react-native-web/src/exports/Picker/index.js @@ -47,7 +47,6 @@ const Picker = forwardRef((props, forwardedRef) => { } = props; const hostRef = useRef(null); - const setRef = useMergeRefs(forwardedRef, hostRef); function handleChange(e: Object) { const { selectedIndex, value } = e.target; @@ -56,18 +55,21 @@ const Picker = forwardRef((props, forwardedRef) => { } } - const supportedProps = { + const supportedProps: any = { children, disabled: enabled === false ? true : undefined, onChange: handleChange, - ref: setRef, style: [styles.initial, style], testID, value: selectedValue, ...other }; - usePlatformMethods(hostRef, supportedProps); + const platformMethodsRef = usePlatformMethods(supportedProps); + + const setRef = useMergeRefs(hostRef, platformMethodsRef, forwardedRef); + + supportedProps.ref = setRef; return createElement('select', supportedProps); }); diff --git a/packages/react-native-web/src/exports/Text/index.js b/packages/react-native-web/src/exports/Text/index.js index cd8396e25..825ba68c0 100644 --- a/packages/react-native-web/src/exports/Text/index.js +++ b/packages/react-native-web/src/exports/Text/index.js @@ -100,7 +100,6 @@ const Text = forwardRef((props, forwardedRef) => { const hasTextAncestor = useContext(TextAncestorContext); const hostRef = useRef(null); - const setRef = useMergeRefs(forwardedRef, hostRef); const classList = [ classes.text, @@ -155,10 +154,12 @@ const Text = forwardRef((props, forwardedRef) => { supportedProps.dir = dir != null ? dir : 'auto'; } supportedProps.onClick = handleClick; - supportedProps.ref = setRef; supportedProps.style = style; - usePlatformMethods(hostRef, supportedProps); + const platformMethodsRef = usePlatformMethods(supportedProps); + const setRef = useMergeRefs(hostRef, platformMethodsRef, forwardedRef); + + supportedProps.ref = setRef; const element = createElement(component, supportedProps); diff --git a/packages/react-native-web/src/exports/TextInput/index.js b/packages/react-native-web/src/exports/TextInput/index.js index bef43a4c9..ebf336ceb 100644 --- a/packages/react-native-web/src/exports/TextInput/index.js +++ b/packages/react-native-web/src/exports/TextInput/index.js @@ -229,8 +229,6 @@ const TextInput = forwardRef((props, forwardedRef) => { [handleContentSizeChange] ); - const setRef = useMergeRefs(forwardedRef, hostRef, imperativeRef); - function handleBlur(e) { TextInputState._currentlyFocusedNode = null; if (onBlur) { @@ -367,14 +365,17 @@ const TextInput = forwardRef((props, forwardedRef) => { supportedProps.onKeyDown = handleKeyDown; supportedProps.onSelect = handleSelectionChange; supportedProps.readOnly = !editable; - supportedProps.ref = setRef; supportedProps.rows = multiline ? numberOfLines : undefined; supportedProps.spellCheck = spellCheck != null ? spellCheck : autoCorrect; supportedProps.style = style; supportedProps.type = multiline ? undefined : type; supportedProps.inputMode = inputMode; - usePlatformMethods(hostRef, supportedProps); + const platformMethodsRef = usePlatformMethods(supportedProps); + + const setRef = useMergeRefs(hostRef, platformMethodsRef, imperativeRef, forwardedRef); + + supportedProps.ref = setRef; return createElement(component, supportedProps); }); diff --git a/packages/react-native-web/src/exports/View/index.js b/packages/react-native-web/src/exports/View/index.js index 0c9a91038..100d35904 100644 --- a/packages/react-native-web/src/exports/View/index.js +++ b/packages/react-native-web/src/exports/View/index.js @@ -102,7 +102,6 @@ const View = forwardRef((props, forwardedRef) => { const hasTextAncestor = useContext(TextAncestorContext); const hostRef = useRef(null); - const setRef = useMergeRefs(forwardedRef, hostRef); const classList = [classes.view]; const style = StyleSheet.compose( @@ -132,10 +131,12 @@ const View = forwardRef((props, forwardedRef) => { const supportedProps = pickProps(props); supportedProps.classList = classList; - supportedProps.ref = setRef; supportedProps.style = style; - usePlatformMethods(hostRef, supportedProps); + const platformMethodsRef = usePlatformMethods(supportedProps); + const setRef = useMergeRefs(hostRef, platformMethodsRef, forwardedRef); + + supportedProps.ref = setRef; return createElement('div', supportedProps); }); diff --git a/packages/react-native-web/src/hooks/usePlatformMethods.js b/packages/react-native-web/src/hooks/usePlatformMethods.js index 4b21333b7..fac1adf33 100644 --- a/packages/react-native-web/src/hooks/usePlatformMethods.js +++ b/packages/react-native-web/src/hooks/usePlatformMethods.js @@ -7,11 +7,9 @@ * @flow */ -import type { ElementRef } from 'react'; - import UIManager from '../exports/UIManager'; import createDOMProps from '../modules/createDOMProps'; -import { useImperativeHandle, useRef } from 'react'; +import { useMemo, useRef } from 'react'; function setNativeProps(node, nativeProps, classList, pointerEvents, style, previousStyleRef) { if (node != null && nativeProps) { @@ -45,14 +43,12 @@ function setNativeProps(node, nativeProps, classList, pointerEvents, style, prev * Adds non-standard methods to the hode element. This is temporarily until an * API like `ReactNative.measure(hostRef, callback)` is added to React Native. */ -export default function usePlatformMethods(hostRef: ElementRef, props: Object) { +export default function usePlatformMethods(props: Object) { const previousStyleRef = useRef(null); const { classList, style, pointerEvents } = props; - useImperativeHandle( - hostRef, - () => { - const hostNode = hostRef.current; + return useMemo( + () => (hostNode: any) => { if (hostNode != null) { hostNode.measure = callback => UIManager.measure(hostNode, callback); hostNode.measureLayout = (relativeToNode, success, failure) => @@ -63,6 +59,6 @@ export default function usePlatformMethods(hostRef: ElementRef, props: Obje } return hostNode; }, - [hostRef, classList, pointerEvents, style] + [classList, pointerEvents, style] ); }