mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-05-13 19:35:41 +00:00
[fix] Order of ref merging
Ensure internal refs are called before the forwardedRef. This ensures that the DOM element mutation performed by usePlatformMethods occurs before user-space refs are called. Ref #1749
This commit is contained in:
@@ -47,7 +47,6 @@ const Picker = forwardRef<PickerProps, *>((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<PickerProps, *>((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);
|
||||
});
|
||||
|
||||
@@ -100,7 +100,6 @@ const Text = forwardRef<TextProps, *>((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<TextProps, *>((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);
|
||||
|
||||
|
||||
@@ -229,8 +229,6 @@ const TextInput = forwardRef<TextInputProps, *>((props, forwardedRef) => {
|
||||
[handleContentSizeChange]
|
||||
);
|
||||
|
||||
const setRef = useMergeRefs(forwardedRef, hostRef, imperativeRef);
|
||||
|
||||
function handleBlur(e) {
|
||||
TextInputState._currentlyFocusedNode = null;
|
||||
if (onBlur) {
|
||||
@@ -367,14 +365,17 @@ const TextInput = forwardRef<TextInputProps, *>((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);
|
||||
});
|
||||
|
||||
@@ -102,7 +102,6 @@ const View = forwardRef<ViewProps, *>((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<ViewProps, *>((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);
|
||||
});
|
||||
|
||||
@@ -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<any>, 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<any>, props: Obje
|
||||
}
|
||||
return hostNode;
|
||||
},
|
||||
[hostRef, classList, pointerEvents, style]
|
||||
[classList, pointerEvents, style]
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user