Skip to content

Commit

Permalink
fix: prevent ref from being called when it shouldn't be
Browse files Browse the repository at this point in the history
  • Loading branch information
imnotjames committed Sep 21, 2020
1 parent 288acaf commit 83eea52
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 62 deletions.
17 changes: 10 additions & 7 deletions packages/react-native-web/src/exports/Picker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import setAndForwardRef from '../../modules/setAndForwardRef';
import usePlatformMethods from '../../hooks/usePlatformMethods';
import PickerItem from './PickerItem';
import StyleSheet, { type StyleObj } from '../StyleSheet';
import { forwardRef, useRef } from 'react';
import { forwardRef, useMemo, useRef } from 'react';

type PickerProps = {
...ViewProps,
Expand Down Expand Up @@ -47,12 +47,15 @@ const Picker = forwardRef<PickerProps, *>((props, forwardedRef) => {
} = props;

const hostRef = useRef(null);
const setRef = setAndForwardRef({
getForwardedRef: () => forwardedRef,
setLocalRef: hostNode => {
hostRef.current = hostNode;
}
});
const setRef = useMemo(
() => setAndForwardRef({
getForwardedRef: () => forwardedRef,
setLocalRef: hostNode => {
hostRef.current = hostNode;
},
}),
[forwardedRef]
);

function handleChange(e: Object) {
const { selectedIndex, value } = e.target;
Expand Down
17 changes: 10 additions & 7 deletions packages/react-native-web/src/exports/Text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import type { TextProps } from './types';

import * as React from 'react';
import { forwardRef, useContext, useRef } from 'react';
import { forwardRef, useContext, useMemo, useRef } from 'react';
import createElement from '../createElement';
import css from '../StyleSheet/css';
import pick from '../../modules/pick';
Expand Down Expand Up @@ -100,12 +100,15 @@ const Text = forwardRef<TextProps, *>((props, forwardedRef) => {

const hasTextAncestor = useContext(TextAncestorContext);
const hostRef = useRef(null);
const setRef = setAndForwardRef({
getForwardedRef: () => forwardedRef,
setLocalRef: hostNode => {
hostRef.current = hostNode;
}
});
const setRef = useMemo(
() => setAndForwardRef({
getForwardedRef: () => forwardedRef,
setLocalRef: hostNode => {
hostRef.current = hostNode;
}
}),
[forwardedRef]
);

const classList = [
classes.text,
Expand Down
89 changes: 48 additions & 41 deletions packages/react-native-web/src/exports/TextInput/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import type { TextInputProps } from './types';

import { forwardRef, useRef } from 'react';
import { forwardRef, useCallback, useMemo, useRef } from 'react';
import createElement from '../createElement';
import css from '../StyleSheet/css';
import pick from '../../modules/pick';
Expand Down Expand Up @@ -188,28 +188,55 @@ const TextInput = forwardRef<TextInputProps, *>((props, forwardedRef) => {

const hostRef = useRef(null);
const dimensions = useRef({ height: null, width: null });
const setRef = setAndForwardRef({
getForwardedRef: () => forwardedRef,
setLocalRef: hostNode => {
// TextInput needs to add more methods to the hostNode in addition to those
// added by `usePlatformMethods`. This is temporarily until an API like
// `TextInput.clear(hostRef)` is added to React Native.
if (hostNode != null) {
hostNode.clear = function() {
if (hostNode != null) {
hostNode.value = '';
}
};
hostNode.isFocused = function() {
return hostNode != null && TextInputState.currentlyFocusedField() === hostNode;
};

const handleContentSizeChange = useCallback(
() => {
const node = hostRef.current;
if (multiline && onContentSizeChange && node != null) {
const newHeight = node.scrollHeight;
const newWidth = node.scrollWidth;
if (newHeight !== dimensions.current.height || newWidth !== dimensions.current.width) {
dimensions.current.height = newHeight;
dimensions.current.width = newWidth;
onContentSizeChange({
nativeEvent: {
contentSize: {
height: dimensions.current.height,
width: dimensions.current.width
}
}
});
}
}
hostRef.current = hostNode;
if (hostRef.current != null) {
handleContentSizeChange();
},
[multiline, onContentSizeChange]
);

const setRef = useMemo(
() => setAndForwardRef({
getForwardedRef: () => forwardedRef,
setLocalRef: hostNode => {
// TextInput needs to add more methods to the hostNode in addition to those
// added by `usePlatformMethods`. This is temporarily until an API like
// `TextInput.clear(hostRef)` is added to React Native.
if (hostNode != null) {
hostNode.clear = function() {
if (hostNode != null) {
hostNode.value = '';
}
};
hostNode.isFocused = function() {
return hostNode != null && TextInputState.currentlyFocusedField() === hostNode;
};
}
hostRef.current = hostNode;
if (hostRef.current != null) {
handleContentSizeChange();
}
}
}
});
}),
[forwardedRef, handleContentSizeChange]
);

function handleBlur(e) {
TextInputState._currentlyFocusedNode = null;
Expand All @@ -219,26 +246,6 @@ const TextInput = forwardRef<TextInputProps, *>((props, forwardedRef) => {
}
}

function handleContentSizeChange() {
const node = hostRef.current;
if (multiline && onContentSizeChange && node != null) {
const newHeight = node.scrollHeight;
const newWidth = node.scrollWidth;
if (newHeight !== dimensions.current.height || newWidth !== dimensions.current.width) {
dimensions.current.height = newHeight;
dimensions.current.width = newWidth;
onContentSizeChange({
nativeEvent: {
contentSize: {
height: dimensions.current.height,
width: dimensions.current.width
}
}
});
}
}
}

function handleChange(e) {
const text = e.target.value;
e.nativeEvent.text = text;
Expand Down
17 changes: 10 additions & 7 deletions packages/react-native-web/src/exports/View/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import type { ViewProps } from './types';

import * as React from 'react';
import { forwardRef, useContext, useRef } from 'react';
import { forwardRef, useContext, useRef, useMemo } from 'react';
import createElement from '../createElement';
import css from '../StyleSheet/css';
import pick from '../../modules/pick';
Expand Down Expand Up @@ -102,12 +102,15 @@ const View = forwardRef<ViewProps, *>((props, forwardedRef) => {

const hasTextAncestor = useContext(TextAncestorContext);
const hostRef = useRef(null);
const setRef = setAndForwardRef({
getForwardedRef: () => forwardedRef,
setLocalRef: hostNode => {
hostRef.current = hostNode;
}
});
const setRef = useMemo(
() => setAndForwardRef({
getForwardedRef: () => forwardedRef,
setLocalRef: hostNode => {
hostRef.current = hostNode;
},
}),
[forwardedRef]
);

const classList = [classes.view];
const style = StyleSheet.compose(
Expand Down

0 comments on commit 83eea52

Please sign in to comment.