From 8ba0db96720b9b5e69f67b242171624d0a1c02b0 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Fri, 12 Oct 2018 11:57:19 -0700 Subject: [PATCH 1/4] Deprecate findDOMNode in StrictMode There are two scenarios. One is that we pass a component instance that is already in strict mode or the node that we find is in strict mode if an outer component renders into strict mode. I use a separate method findHostInstanceWithWarning for this so that a) I can pass the method name (findDOMNode/findNodeHandle). b) Can ignore this warning in React Native mixins/NativeComponent that use this helper. I don't want to expose the fiber to the renderers themselves. --- .../src/__tests__/findDOMNode-test.js | 68 +++++++++++++++- packages/react-dom/src/client/ReactDOM.js | 7 +- .../react-native-renderer/src/ReactFabric.js | 13 +++- .../src/ReactNativeRenderer.js | 13 +++- .../__tests__/ReactFabric-test.internal.js | 77 +++++++++++++++++++ .../ReactNativeMount-test.internal.js | 77 +++++++++++++++++++ .../src/createReactNoop.js | 6 ++ .../src/ReactFiberReconciler.js | 68 ++++++++++++++++ ...eactIncrementalReflection-test.internal.js | 27 +++++-- 9 files changed, 345 insertions(+), 11 deletions(-) diff --git a/packages/react-dom/src/__tests__/findDOMNode-test.js b/packages/react-dom/src/__tests__/findDOMNode-test.js index 2e7dab041f1..54e583be3ec 100644 --- a/packages/react-dom/src/__tests__/findDOMNode-test.js +++ b/packages/react-dom/src/__tests__/findDOMNode-test.js @@ -12,6 +12,7 @@ const React = require('react'); const ReactDOM = require('react-dom'); const ReactTestUtils = require('react-dom/test-utils'); +const StrictMode = React.StrictMode; describe('findDOMNode', () => { it('findDOMNode should return null if passed null', () => { @@ -94,7 +95,72 @@ describe('findDOMNode', () => { return
; } } - expect(() => ReactTestUtils.renderIntoDocument()).not.toThrow(); }); + + it('findDOMNode should warn if used to find a host component inside StrictMode', () => { + let parent = undefined; + let child = undefined; + + class ContainsStrictModeChild extends React.Component { + render() { + return ( + +
(child = n)} /> + + ); + } + } + + ReactTestUtils.renderIntoDocument( + (parent = n)} />, + ); + + let match; + expect(() => (match = ReactDOM.findDOMNode(parent))).toWarnDev([ + 'Warning: findDOMNode is deprecated in StrictMode. ' + + 'findDOMNode was passed an instance of ContainsStrictModeChild which renders a StrictMode subtree. ' + + 'The nearest child is in StrictMode. ' + + 'Use an explicit ref directly on the element you want to get a handle on.' + + '\n' + + '\n in div (at **)' + + '\n in StrictMode (at **)' + + '\n in ContainsStrictModeChild (at **)' + + '\n' + + '\nLearn more about using refs safely here:' + + '\nhttps://fb.me/react-strict-mode-find-node', + ]); + expect(match).toBe(child); + }); + + it('findDOMNode should warn if passed a component that is inside StrictMode', () => { + let parent = undefined; + let child = undefined; + + class IsInStrictMode extends React.Component { + render() { + return
(child = n)} />; + } + } + + ReactTestUtils.renderIntoDocument( + + (parent = n)} /> + , + ); + + let match; + expect(() => (match = ReactDOM.findDOMNode(parent))).toWarnDev([ + 'Warning: findDOMNode is deprecated in StrictMode. ' + + 'findDOMNode was passed an instance of IsInStrictMode which is in a StrictMode subtree. ' + + 'Use an explicit ref directly on the element you want to get a handle on.' + + '\n' + + '\n in IsInStrictMode (at **)' + + '\n in StrictMode (at **)' + + '\n' + + '\nLearn more about using refs safely here:' + + '\nhttps://fb.me/react-strict-mode-find-node', + ]); + expect(match).toBe(child); + }); }); diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 83563ee14f9..9803142d41f 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -614,7 +614,12 @@ const ReactDOM: Object = { if ((componentOrElement: any).nodeType === ELEMENT_NODE) { return (componentOrElement: any); } - + if (__DEV__) { + return DOMRenderer.findHostInstanceWithWarning( + componentOrElement, + 'findDOMNode', + ); + } return DOMRenderer.findHostInstance(componentOrElement); }, diff --git a/packages/react-native-renderer/src/ReactFabric.js b/packages/react-native-renderer/src/ReactFabric.js index 806bfb0080e..77914d1c388 100644 --- a/packages/react-native-renderer/src/ReactFabric.js +++ b/packages/react-native-renderer/src/ReactFabric.js @@ -29,6 +29,8 @@ import warningWithoutStack from 'shared/warningWithoutStack'; const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; const findHostInstance = ReactFabricRenderer.findHostInstance; +const findHostInstanceWithWarning = + ReactFabricRenderer.findHostInstanceWithWarning; function findNodeHandle(componentOrHandle: any): ?number { if (__DEV__) { @@ -60,7 +62,16 @@ function findNodeHandle(componentOrHandle: any): ?number { if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) { return componentOrHandle.canonical._nativeTag; } - const hostInstance = findHostInstance(componentOrHandle); + let hostInstance; + if (__DEV__) { + hostInstance = findHostInstanceWithWarning( + componentOrHandle, + 'findNodeHandle', + ); + } else { + hostInstance = findHostInstance(componentOrHandle); + } + if (hostInstance == null) { return hostInstance; } diff --git a/packages/react-native-renderer/src/ReactNativeRenderer.js b/packages/react-native-renderer/src/ReactNativeRenderer.js index 203c3db213e..2414c540f86 100644 --- a/packages/react-native-renderer/src/ReactNativeRenderer.js +++ b/packages/react-native-renderer/src/ReactNativeRenderer.js @@ -32,6 +32,8 @@ import warningWithoutStack from 'shared/warningWithoutStack'; const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; const findHostInstance = ReactNativeFiberRenderer.findHostInstance; +const findHostInstanceWithWarning = + ReactNativeFiberRenderer.findHostInstanceWithWarning; function findNodeHandle(componentOrHandle: any): ?number { if (__DEV__) { @@ -63,7 +65,16 @@ function findNodeHandle(componentOrHandle: any): ?number { if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) { return componentOrHandle.canonical._nativeTag; } - const hostInstance = findHostInstance(componentOrHandle); + let hostInstance; + if (__DEV__) { + hostInstance = findHostInstanceWithWarning( + componentOrHandle, + 'findNodeHandle', + ); + } else { + hostInstance = findHostInstance(componentOrHandle); + } + if (hostInstance == null) { return hostInstance; } diff --git a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js index d81c084af3e..9c35d75175c 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js @@ -15,6 +15,7 @@ let ReactFabric; let createReactNativeComponentClass; let UIManager; let FabricUIManager; +let StrictMode; jest.mock('shared/ReactFeatureFlags', () => require('shared/forks/ReactFeatureFlags.native-fabric-oss'), @@ -25,6 +26,7 @@ describe('ReactFabric', () => { jest.resetModules(); React = require('react'); + StrictMode = React.StrictMode; ReactFabric = require('react-native-renderer/fabric'); FabricUIManager = require('FabricUIManager'); UIManager = require('UIManager'); @@ -436,4 +438,79 @@ describe('ReactFabric', () => { // This could change in the future. expect(touchStart2).toBeCalled(); }); + + it('findNodeHandle should warn if used to find a host component inside StrictMode', () => { + const View = createReactNativeComponentClass('RCTView', () => ({ + validAttributes: {foo: true}, + uiViewClassName: 'RCTView', + })); + + let parent = undefined; + let child = undefined; + + class ContainsStrictModeChild extends React.Component { + render() { + return ( + + (child = n)} /> + + ); + } + } + + ReactFabric.render( (parent = n)} />, 11); + + let match; + expect(() => (match = ReactFabric.findNodeHandle(parent))).toWarnDev([ + 'Warning: findNodeHandle is deprecated in StrictMode. ' + + 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders a StrictMode subtree. ' + + 'The nearest child is in StrictMode. ' + + 'Use an explicit ref directly on the element you want to get a handle on.' + + '\n' + + '\n in RCTView (at **)' + + '\n in StrictMode (at **)' + + '\n in ContainsStrictModeChild (at **)' + + '\n' + + '\nLearn more about using refs safely here:' + + '\nhttps://fb.me/react-strict-mode-find-node', + ]); + expect(match).toBe(child._nativeTag); + }); + + it('findNodeHandle should warn if passed a component that is inside StrictMode', () => { + const View = createReactNativeComponentClass('RCTView', () => ({ + validAttributes: {foo: true}, + uiViewClassName: 'RCTView', + })); + + let parent = undefined; + let child = undefined; + + class IsInStrictMode extends React.Component { + render() { + return (child = n)} />; + } + } + + ReactFabric.render( + + (parent = n)} /> + , + 11, + ); + + let match; + expect(() => (match = ReactFabric.findNodeHandle(parent))).toWarnDev([ + 'Warning: findNodeHandle is deprecated in StrictMode. ' + + 'findNodeHandle was passed an instance of IsInStrictMode which is in a StrictMode subtree. ' + + 'Use an explicit ref directly on the element you want to get a handle on.' + + '\n' + + '\n in IsInStrictMode (at **)' + + '\n in StrictMode (at **)' + + '\n' + + '\nLearn more about using refs safely here:' + + '\nhttps://fb.me/react-strict-mode-find-node', + ]); + expect(match).toBe(child._nativeTag); + }); }); diff --git a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js index 79381c3db95..3ea9ee213ba 100644 --- a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js @@ -11,6 +11,7 @@ 'use strict'; let React; +let StrictMode; let ReactNative; let createReactNativeComponentClass; let UIManager; @@ -20,6 +21,7 @@ describe('ReactNative', () => { jest.resetModules(); React = require('react'); + StrictMode = React.StrictMode; ReactNative = require('react-native-renderer'); UIManager = require('UIManager'); createReactNativeComponentClass = require('ReactNativeViewConfigRegistry') @@ -258,4 +260,79 @@ describe('ReactNative', () => { 11, ); }); + + it('findNodeHandle should warn if used to find a host component inside StrictMode', () => { + const View = createReactNativeComponentClass('RCTView', () => ({ + validAttributes: {foo: true}, + uiViewClassName: 'RCTView', + })); + + let parent = undefined; + let child = undefined; + + class ContainsStrictModeChild extends React.Component { + render() { + return ( + + (child = n)} /> + + ); + } + } + + ReactNative.render( (parent = n)} />, 11); + + let match; + expect(() => (match = ReactNative.findNodeHandle(parent))).toWarnDev([ + 'Warning: findNodeHandle is deprecated in StrictMode. ' + + 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders a StrictMode subtree. ' + + 'The nearest child is in StrictMode. ' + + 'Use an explicit ref directly on the element you want to get a handle on.' + + '\n' + + '\n in RCTView (at **)' + + '\n in StrictMode (at **)' + + '\n in ContainsStrictModeChild (at **)' + + '\n' + + '\nLearn more about using refs safely here:' + + '\nhttps://fb.me/react-strict-mode-find-node', + ]); + expect(match).toBe(child._nativeTag); + }); + + it('findNodeHandle should warn if passed a component that is inside StrictMode', () => { + const View = createReactNativeComponentClass('RCTView', () => ({ + validAttributes: {foo: true}, + uiViewClassName: 'RCTView', + })); + + let parent = undefined; + let child = undefined; + + class IsInStrictMode extends React.Component { + render() { + return (child = n)} />; + } + } + + ReactNative.render( + + (parent = n)} /> + , + 11, + ); + + let match; + expect(() => (match = ReactNative.findNodeHandle(parent))).toWarnDev([ + 'Warning: findNodeHandle is deprecated in StrictMode. ' + + 'findNodeHandle was passed an instance of IsInStrictMode which is in a StrictMode subtree. ' + + 'Use an explicit ref directly on the element you want to get a handle on.' + + '\n' + + '\n in IsInStrictMode (at **)' + + '\n in StrictMode (at **)' + + '\n' + + '\nLearn more about using refs safely here:' + + '\nhttps://fb.me/react-strict-mode-find-node', + ]); + expect(match).toBe(child._nativeTag); + }); }); diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js index 5cb913b5d1a..00fab26d8e2 100644 --- a/packages/react-noop-renderer/src/createReactNoop.js +++ b/packages/react-noop-renderer/src/createReactNoop.js @@ -522,6 +522,12 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { if (typeof component.id === 'number') { return component; } + if (__DEV__) { + return NoopRenderer.findHostInstanceWithWarning( + component, + 'findInstance', + ); + } return NoopRenderer.findHostInstance(component); }, diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index ca072d0c938..7fec0fd2759 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -61,6 +61,8 @@ import { import {createUpdate, enqueueUpdate} from './ReactUpdateQueue'; import ReactFiberInstrumentation from './ReactFiberInstrumentation'; import * as ReactCurrentFiber from './ReactCurrentFiber'; +import {getStackByFiberInDevAndProd} from './ReactCurrentFiber'; +import {StrictMode} from './ReactTypeOfMode'; type OpaqueRoot = FiberRoot; @@ -82,9 +84,11 @@ type DevToolsConfig = {| |}; let didWarnAboutNestedUpdates; +let didWarnAboutFindNodeInStrictMode; if (__DEV__) { didWarnAboutNestedUpdates = false; + didWarnAboutFindNodeInStrictMode = {}; } function getContextForSubtree( @@ -209,6 +213,68 @@ function findHostInstance(component: Object): PublicInstance | null { return hostFiber.stateNode; } +function findHostInstanceWithWarning( + component: Object, + methodName: string, +): PublicInstance | null { + if (__DEV__) { + const fiber = ReactInstanceMap.get(component); + if (fiber === undefined) { + if (typeof component.render === 'function') { + invariant(false, 'Unable to find node on an unmounted component.'); + } else { + invariant( + false, + 'Argument appears to not be a ReactComponent. Keys: %s', + Object.keys(component), + ); + } + } + const hostFiber = findCurrentHostFiber(fiber); + if (hostFiber === null) { + return null; + } + if (hostFiber.mode & StrictMode) { + const componentName = getComponentName(fiber.type) || 'Component'; + if (!didWarnAboutFindNodeInStrictMode[componentName]) { + didWarnAboutFindNodeInStrictMode[componentName] = true; + if (fiber.mode & StrictMode) { + warningWithoutStack( + false, + '%s is deprecated in StrictMode. ' + + '%s was passed an instance of %s which is in a StrictMode subtree. ' + + 'Use an explicit ref directly on the element you want to get a handle on.' + + '\n%s' + + '\n\nLearn more about using refs safely here:' + + '\nhttps://fb.me/react-strict-mode-find-node', + methodName, + methodName, + componentName, + getStackByFiberInDevAndProd(fiber), + ); + } else { + warningWithoutStack( + false, + '%s is deprecated in StrictMode. ' + + '%s was passed an instance of %s which renders a StrictMode subtree. ' + + 'The nearest child is in StrictMode. ' + + 'Use an explicit ref directly on the element you want to get a handle on.' + + '\n%s' + + '\n\nLearn more about using refs safely here:' + + '\nhttps://fb.me/react-strict-mode-find-node', + methodName, + methodName, + componentName, + getStackByFiberInDevAndProd(hostFiber), + ); + } + } + } + return hostFiber.stateNode; + } + return findHostInstance(component); +} + export function createContainer( containerInfo: Container, isConcurrent: boolean, @@ -266,6 +332,8 @@ export function getPublicRootInstance( export {findHostInstance}; +export {findHostInstanceWithWarning}; + export function findHostInstanceWithNoPortals( fiber: Fiber, ): PublicInstance | null { diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.internal.js index b19d7de430b..fa3dc6e7e01 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.internal.js @@ -138,22 +138,35 @@ describe('ReactIncrementalReflection', () => { let classInstance = null; + function findInstance(inst) { + // We ignore warnings fired by findInstance because we are testing + // that the actual behavior still works as expected even though it + // is deprecated. + let oldConsoleError = console.error; + console.error = jest.fn(); + try { + return ReactNoop.findInstance(inst); + } finally { + console.error = oldConsoleError; + } + } + class Component extends React.Component { UNSAFE_componentWillMount() { classInstance = this; - ops.push('componentWillMount', ReactNoop.findInstance(this)); + ops.push('componentWillMount', findInstance(this)); } componentDidMount() { - ops.push('componentDidMount', ReactNoop.findInstance(this)); + ops.push('componentDidMount', findInstance(this)); } UNSAFE_componentWillUpdate() { - ops.push('componentWillUpdate', ReactNoop.findInstance(this)); + ops.push('componentWillUpdate', findInstance(this)); } componentDidUpdate() { - ops.push('componentDidUpdate', ReactNoop.findInstance(this)); + ops.push('componentDidUpdate', findInstance(this)); } componentWillUnmount() { - ops.push('componentWillUnmount', ReactNoop.findInstance(this)); + ops.push('componentWillUnmount', findInstance(this)); } render() { ops.push('render'); @@ -193,7 +206,7 @@ describe('ReactIncrementalReflection', () => { expect(classInstance).toBeDefined(); // The instance has been complete but is still not committed so it should // not find any host nodes in it. - expect(ReactNoop.findInstance(classInstance)).toBe(null); + expect(findInstance(classInstance)).toBe(null); expect(ReactNoop.flush).toWarnDev( 'componentWillMount: Please update the following components ' + @@ -206,7 +219,7 @@ describe('ReactIncrementalReflection', () => { const hostSpan = classInstance.span; expect(hostSpan).toBeDefined(); - expect(ReactNoop.findInstance(classInstance)).toBe(hostSpan); + expect(findInstance(classInstance)).toBe(hostSpan); expect(ops).toEqual(['componentDidMount', hostSpan]); From 42caeed8619db1b09ece18835c4133db6afe8c20 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Fri, 12 Oct 2018 15:04:26 -0700 Subject: [PATCH 2/4] Update warning message --- packages/react-dom/src/__tests__/findDOMNode-test.js | 9 ++++----- .../src/__tests__/ReactFabric-test.internal.js | 9 ++++----- .../src/__tests__/ReactNativeMount-test.internal.js | 9 ++++----- packages/react-reconciler/src/ReactFiberReconciler.js | 9 ++++----- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/packages/react-dom/src/__tests__/findDOMNode-test.js b/packages/react-dom/src/__tests__/findDOMNode-test.js index 54e583be3ec..43af38fcf47 100644 --- a/packages/react-dom/src/__tests__/findDOMNode-test.js +++ b/packages/react-dom/src/__tests__/findDOMNode-test.js @@ -119,9 +119,8 @@ describe('findDOMNode', () => { let match; expect(() => (match = ReactDOM.findDOMNode(parent))).toWarnDev([ 'Warning: findDOMNode is deprecated in StrictMode. ' + - 'findDOMNode was passed an instance of ContainsStrictModeChild which renders a StrictMode subtree. ' + - 'The nearest child is in StrictMode. ' + - 'Use an explicit ref directly on the element you want to get a handle on.' + + 'findDOMNode was passed an instance of ContainsStrictModeChild which renders a StrictMode children. ' + + 'Instead, add a ref directly to the element you want to reference.' + '\n' + '\n in div (at **)' + '\n in StrictMode (at **)' + @@ -152,8 +151,8 @@ describe('findDOMNode', () => { let match; expect(() => (match = ReactDOM.findDOMNode(parent))).toWarnDev([ 'Warning: findDOMNode is deprecated in StrictMode. ' + - 'findDOMNode was passed an instance of IsInStrictMode which is in a StrictMode subtree. ' + - 'Use an explicit ref directly on the element you want to get a handle on.' + + 'findDOMNode was passed an instance of IsInStrictMode which is inside StrictMode. ' + + 'Instead, add a ref directly to the element you want to reference.' + '\n' + '\n in IsInStrictMode (at **)' + '\n in StrictMode (at **)' + diff --git a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js index 9c35d75175c..292a81fc315 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js @@ -463,9 +463,8 @@ describe('ReactFabric', () => { let match; expect(() => (match = ReactFabric.findNodeHandle(parent))).toWarnDev([ 'Warning: findNodeHandle is deprecated in StrictMode. ' + - 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders a StrictMode subtree. ' + - 'The nearest child is in StrictMode. ' + - 'Use an explicit ref directly on the element you want to get a handle on.' + + 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders a StrictMode children. ' + + 'Instead, add a ref directly to the element you want to reference.' + '\n' + '\n in RCTView (at **)' + '\n in StrictMode (at **)' + @@ -502,8 +501,8 @@ describe('ReactFabric', () => { let match; expect(() => (match = ReactFabric.findNodeHandle(parent))).toWarnDev([ 'Warning: findNodeHandle is deprecated in StrictMode. ' + - 'findNodeHandle was passed an instance of IsInStrictMode which is in a StrictMode subtree. ' + - 'Use an explicit ref directly on the element you want to get a handle on.' + + 'findNodeHandle was passed an instance of IsInStrictMode which is inside StrictMode. ' + + 'Instead, add a ref directly to the element you want to reference.' + '\n' + '\n in IsInStrictMode (at **)' + '\n in StrictMode (at **)' + diff --git a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js index 3ea9ee213ba..174fd2f5d08 100644 --- a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js @@ -285,9 +285,8 @@ describe('ReactNative', () => { let match; expect(() => (match = ReactNative.findNodeHandle(parent))).toWarnDev([ 'Warning: findNodeHandle is deprecated in StrictMode. ' + - 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders a StrictMode subtree. ' + - 'The nearest child is in StrictMode. ' + - 'Use an explicit ref directly on the element you want to get a handle on.' + + 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders a StrictMode children. ' + + 'Instead, add a ref directly to the element you want to reference.' + '\n' + '\n in RCTView (at **)' + '\n in StrictMode (at **)' + @@ -324,8 +323,8 @@ describe('ReactNative', () => { let match; expect(() => (match = ReactNative.findNodeHandle(parent))).toWarnDev([ 'Warning: findNodeHandle is deprecated in StrictMode. ' + - 'findNodeHandle was passed an instance of IsInStrictMode which is in a StrictMode subtree. ' + - 'Use an explicit ref directly on the element you want to get a handle on.' + + 'findNodeHandle was passed an instance of IsInStrictMode which is inside StrictMode. ' + + 'Instead, add a ref directly to the element you want to reference.' + '\n' + '\n in IsInStrictMode (at **)' + '\n in StrictMode (at **)' + diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index 7fec0fd2759..5ca0b95abcb 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -242,8 +242,8 @@ function findHostInstanceWithWarning( warningWithoutStack( false, '%s is deprecated in StrictMode. ' + - '%s was passed an instance of %s which is in a StrictMode subtree. ' + - 'Use an explicit ref directly on the element you want to get a handle on.' + + '%s was passed an instance of %s which is inside StrictMode. ' + + 'Instead, add a ref directly to the element you want to reference.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-find-node', @@ -256,9 +256,8 @@ function findHostInstanceWithWarning( warningWithoutStack( false, '%s is deprecated in StrictMode. ' + - '%s was passed an instance of %s which renders a StrictMode subtree. ' + - 'The nearest child is in StrictMode. ' + - 'Use an explicit ref directly on the element you want to get a handle on.' + + '%s was passed an instance of %s which renders a StrictMode children. ' + + 'Instead, add a ref directly to the element you want to reference.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-find-node', From 9e6960da0ad1cae7ec1be9ad16dda911dee25cf2 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Fri, 12 Oct 2018 15:06:48 -0700 Subject: [PATCH 3/4] Use full stack even when the target argument is in strict --- packages/react-dom/src/__tests__/findDOMNode-test.js | 1 + .../src/__tests__/ReactFabric-test.internal.js | 1 + .../src/__tests__/ReactNativeMount-test.internal.js | 1 + packages/react-reconciler/src/ReactFiberReconciler.js | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/react-dom/src/__tests__/findDOMNode-test.js b/packages/react-dom/src/__tests__/findDOMNode-test.js index 43af38fcf47..e8c27efa0fa 100644 --- a/packages/react-dom/src/__tests__/findDOMNode-test.js +++ b/packages/react-dom/src/__tests__/findDOMNode-test.js @@ -154,6 +154,7 @@ describe('findDOMNode', () => { 'findDOMNode was passed an instance of IsInStrictMode which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference.' + '\n' + + '\n in div (at **)' + '\n in IsInStrictMode (at **)' + '\n in StrictMode (at **)' + '\n' + diff --git a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js index 292a81fc315..1d6e3d7e8a0 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js @@ -504,6 +504,7 @@ describe('ReactFabric', () => { 'findNodeHandle was passed an instance of IsInStrictMode which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference.' + '\n' + + '\n in RCTView (at **)' + '\n in IsInStrictMode (at **)' + '\n in StrictMode (at **)' + '\n' + diff --git a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js index 174fd2f5d08..277a625b0c4 100644 --- a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js @@ -326,6 +326,7 @@ describe('ReactNative', () => { 'findNodeHandle was passed an instance of IsInStrictMode which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference.' + '\n' + + '\n in RCTView (at **)' + '\n in IsInStrictMode (at **)' + '\n in StrictMode (at **)' + '\n' + diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index 5ca0b95abcb..b980e4be1f2 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -250,7 +250,7 @@ function findHostInstanceWithWarning( methodName, methodName, componentName, - getStackByFiberInDevAndProd(fiber), + getStackByFiberInDevAndProd(hostFiber), ); } else { warningWithoutStack( From 665596c125252601cd38041a10a3c9d60c589e33 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Fri, 12 Oct 2018 15:28:49 -0700 Subject: [PATCH 4/4] rm a --- packages/react-dom/src/__tests__/findDOMNode-test.js | 2 +- .../src/__tests__/ReactFabric-test.internal.js | 2 +- .../src/__tests__/ReactNativeMount-test.internal.js | 2 +- packages/react-reconciler/src/ReactFiberReconciler.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-dom/src/__tests__/findDOMNode-test.js b/packages/react-dom/src/__tests__/findDOMNode-test.js index e8c27efa0fa..2be58e0c671 100644 --- a/packages/react-dom/src/__tests__/findDOMNode-test.js +++ b/packages/react-dom/src/__tests__/findDOMNode-test.js @@ -119,7 +119,7 @@ describe('findDOMNode', () => { let match; expect(() => (match = ReactDOM.findDOMNode(parent))).toWarnDev([ 'Warning: findDOMNode is deprecated in StrictMode. ' + - 'findDOMNode was passed an instance of ContainsStrictModeChild which renders a StrictMode children. ' + + 'findDOMNode was passed an instance of ContainsStrictModeChild which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference.' + '\n' + '\n in div (at **)' + diff --git a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js index 1d6e3d7e8a0..8281020d488 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js @@ -463,7 +463,7 @@ describe('ReactFabric', () => { let match; expect(() => (match = ReactFabric.findNodeHandle(parent))).toWarnDev([ 'Warning: findNodeHandle is deprecated in StrictMode. ' + - 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders a StrictMode children. ' + + 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference.' + '\n' + '\n in RCTView (at **)' + diff --git a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js index 277a625b0c4..3921aa1eb67 100644 --- a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js @@ -285,7 +285,7 @@ describe('ReactNative', () => { let match; expect(() => (match = ReactNative.findNodeHandle(parent))).toWarnDev([ 'Warning: findNodeHandle is deprecated in StrictMode. ' + - 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders a StrictMode children. ' + + 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference.' + '\n' + '\n in RCTView (at **)' + diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index b980e4be1f2..4d383f33549 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -256,7 +256,7 @@ function findHostInstanceWithWarning( warningWithoutStack( false, '%s is deprecated in StrictMode. ' + - '%s was passed an instance of %s which renders a StrictMode children. ' + + '%s was passed an instance of %s which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference.' + '\n%s' + '\n\nLearn more about using refs safely here:' +