diff --git a/packages/react-native-web/src/exports/Text/__tests__/index-test.js b/packages/react-native-web/src/exports/Text/__tests__/index-test.js
index 78c32960..9b7caeb7 100644
--- a/packages/react-native-web/src/exports/Text/__tests__/index-test.js
+++ b/packages/react-native-web/src/exports/Text/__tests__/index-test.js
@@ -123,6 +123,19 @@ describe('components/Text', () => {
expect(ref).toBeCalled();
});
+ test('is not called for prop changes', () => {
+ const ref = jest.fn();
+ let rerender;
+ act(() => {
+ ({ rerender } = render());
+ });
+ expect(ref).toHaveBeenCalledTimes(1);
+ act(() => {
+ rerender();
+ });
+ expect(ref).toHaveBeenCalledTimes(1);
+ });
+
test('node has imperative methods', () => {
const ref = React.createRef();
act(() => {
diff --git a/packages/react-native-web/src/exports/View/__tests__/index-test.js b/packages/react-native-web/src/exports/View/__tests__/index-test.js
index f5d51446..8aeba2d9 100644
--- a/packages/react-native-web/src/exports/View/__tests__/index-test.js
+++ b/packages/react-native-web/src/exports/View/__tests__/index-test.js
@@ -127,15 +127,15 @@ describe('components/View', () => {
expect(ref).toBeCalled();
});
- test('is not called for props changes', () => {
+ test('is not called for prop changes', () => {
const ref = jest.fn();
let rerender;
act(() => {
- ({ rerender } = render());
+ ({ rerender } = render());
});
expect(ref).toHaveBeenCalledTimes(1);
act(() => {
- rerender();
+ rerender();
});
expect(ref).toHaveBeenCalledTimes(1);
});
diff --git a/packages/react-native-web/src/modules/usePlatformMethods/index.js b/packages/react-native-web/src/modules/usePlatformMethods/index.js
index 15b50a7d..48ce8b8b 100644
--- a/packages/react-native-web/src/modules/usePlatformMethods/index.js
+++ b/packages/react-native-web/src/modules/usePlatformMethods/index.js
@@ -7,9 +7,15 @@
* @flow
*/
+import type { GenericStyleProp } from '../../types';
+import type { ViewProps } from '../../Exports/View';
+
import UIManager from '../../exports/UIManager';
import createDOMProps from '../createDOMProps';
-import { useMemo, useRef } from 'react';
+import useStable from '../useStable';
+import { useRef } from 'react';
+
+const emptyObject = {};
function setNativeProps(node, nativeProps, classList, pointerEvents, style, previousStyleRef) {
if (node != null && nativeProps) {
@@ -43,22 +49,33 @@ 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(props: Object) {
+export default function usePlatformMethods({
+ classList,
+ pointerEvents,
+ style
+}: {
+ classList?: Array,
+ style?: GenericStyleProp<*>,
+ pointerEvents?: $PropertyType
+}) {
const previousStyleRef = useRef(null);
- const { classList, style, pointerEvents } = props;
+ const setNativePropsArgsRef = useRef(null);
+ setNativePropsArgsRef.current = { classList, pointerEvents, style };
- return useMemo(
- () => (hostNode: any) => {
- if (hostNode != null) {
- hostNode.measure = callback => UIManager.measure(hostNode, callback);
- hostNode.measureLayout = (relativeToNode, success, failure) =>
- UIManager.measureLayout(hostNode, relativeToNode, failure, success);
- hostNode.measureInWindow = callback => UIManager.measureInWindow(hostNode, callback);
- hostNode.setNativeProps = nativeProps =>
- setNativeProps(hostNode, nativeProps, classList, pointerEvents, style, previousStyleRef);
- }
- return hostNode;
- },
- [classList, pointerEvents, style]
- );
+ // Avoid creating a new ref on every render. The props only need to be
+ // available to 'setNativeProps' when it is called.
+ const ref = useStable(() => (hostNode: any) => {
+ if (hostNode != null) {
+ hostNode.measure = callback => UIManager.measure(hostNode, callback);
+ hostNode.measureLayout = (relativeToNode, success, failure) =>
+ UIManager.measureLayout(hostNode, relativeToNode, failure, success);
+ hostNode.measureInWindow = callback => UIManager.measureInWindow(hostNode, callback);
+ hostNode.setNativeProps = nativeProps => {
+ const { classList, style, pointerEvents } = setNativePropsArgsRef.current || emptyObject;
+ setNativeProps(hostNode, nativeProps, classList, pointerEvents, style, previousStyleRef);
+ };
+ }
+ });
+
+ return ref;
}