@@ -61,6 +61,8 @@ import {
6161import { createUpdate , enqueueUpdate } from './ReactUpdateQueue' ;
6262import ReactFiberInstrumentation from './ReactFiberInstrumentation' ;
6363import * as ReactCurrentFiber from './ReactCurrentFiber' ;
64+ import { getStackByFiberInDevAndProd } from './ReactCurrentFiber' ;
65+ import { StrictMode } from './ReactTypeOfMode' ;
6466
6567type OpaqueRoot = FiberRoot ;
6668
@@ -82,9 +84,11 @@ type DevToolsConfig = {|
8284| } ;
8385
8486let didWarnAboutNestedUpdates ;
87+ let didWarnAboutFindNodeInStrictMode ;
8588
8689if ( __DEV__ ) {
8790 didWarnAboutNestedUpdates = false ;
91+ didWarnAboutFindNodeInStrictMode = { } ;
8892}
8993
9094function getContextForSubtree (
@@ -209,6 +213,68 @@ function findHostInstance(component: Object): PublicInstance | null {
209213 return hostFiber . stateNode ;
210214}
211215
216+ function findHostInstanceWithWarning (
217+ component : Object ,
218+ methodName : string ,
219+ ) : PublicInstance | null {
220+ if ( __DEV__ ) {
221+ const fiber = ReactInstanceMap . get ( component ) ;
222+ if ( fiber === undefined ) {
223+ if ( typeof component . render === 'function' ) {
224+ invariant ( false , 'Unable to find node on an unmounted component.' ) ;
225+ } else {
226+ invariant (
227+ false ,
228+ 'Argument appears to not be a ReactComponent. Keys: %s' ,
229+ Object . keys ( component ) ,
230+ ) ;
231+ }
232+ }
233+ const hostFiber = findCurrentHostFiber ( fiber ) ;
234+ if ( hostFiber === null ) {
235+ return null ;
236+ }
237+ if ( hostFiber . mode & StrictMode ) {
238+ const componentName = getComponentName ( fiber . type ) || 'Component' ;
239+ if ( ! didWarnAboutFindNodeInStrictMode [ componentName ] ) {
240+ didWarnAboutFindNodeInStrictMode [ componentName ] = true ;
241+ if ( fiber . mode & StrictMode ) {
242+ warningWithoutStack (
243+ false ,
244+ '%s is deprecated in StrictMode. ' +
245+ '%s was passed an instance of %s which is in a StrictMode subtree. ' +
246+ 'Use an explicit ref directly on the element you want to get a handle on.' +
247+ '\n%s' +
248+ '\n\nLearn more about using refs safely here:' +
249+ '\nhttps://fb.me/react-strict-mode-find-node' ,
250+ methodName ,
251+ methodName ,
252+ componentName ,
253+ getStackByFiberInDevAndProd ( fiber ) ,
254+ ) ;
255+ } else {
256+ warningWithoutStack (
257+ false ,
258+ '%s is deprecated in StrictMode. ' +
259+ '%s was passed an instance of %s which renders a StrictMode subtree. ' +
260+ 'The nearest child is in StrictMode. ' +
261+ 'Use an explicit ref directly on the element you want to get a handle on.' +
262+ '\n%s' +
263+ '\n\nLearn more about using refs safely here:' +
264+ '\nhttps://fb.me/react-strict-mode-find-node' ,
265+ methodName ,
266+ methodName ,
267+ componentName ,
268+ getStackByFiberInDevAndProd ( hostFiber ) ,
269+ ) ;
270+ }
271+ }
272+ }
273+ return hostFiber . stateNode ;
274+ }
275+ return findHostInstance ( component ) ;
276+ }
277+
212278export function createContainer (
213279 containerInfo : Container ,
214280 isConcurrent : boolean ,
@@ -266,6 +332,8 @@ export function getPublicRootInstance(
266332
267333export { findHostInstance } ;
268334
335+ export { findHostInstanceWithWarning } ;
336+
269337export function findHostInstanceWithNoPortals (
270338 fiber : Fiber ,
271339) : PublicInstance | null {
0 commit comments