main
js 178 lines 5.19 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @emails react-core
8 */
9
10 'use strict';
11
12 const React = require('react');
13 const ReactDOM = require('react-dom');
14 const StrictMode = React.StrictMode;
15 const assertConsoleErrorDev =
16 require('internal-test-utils').assertConsoleErrorDev;
17
18 describe('findDOMNode', () => {
19 // @gate www && classic
20 it('findDOMNode should return null if passed null', () => {
21 expect(ReactDOM.findDOMNode(null)).toBe(null);
22 });
23
24 // @gate www && classic && !disableLegacyMode
25 it('findDOMNode should find dom element', () => {
26 class MyNode extends React.Component {
27 render() {
28 return (
29 <div>
30 <span>Noise</span>
31 </div>
32 );
33 }
34 }
35
36 const container = document.createElement('div');
37 const myNode = ReactDOM.render(<MyNode />, container);
38 const myDiv = ReactDOM.findDOMNode(myNode);
39 const mySameDiv = ReactDOM.findDOMNode(myDiv);
40 expect(myDiv.tagName).toBe('DIV');
41 expect(mySameDiv).toBe(myDiv);
42 });
43
44 // @gate www && classic && !disableLegacyMode
45 it('findDOMNode should find dom element after an update from null', () => {
46 function Bar({flag}) {
47 if (flag) {
48 return <span>A</span>;
49 }
50 return null;
51 }
52 class MyNode extends React.Component {
53 render() {
54 return <Bar flag={this.props.flag} />;
55 }
56 }
57
58 const container = document.createElement('div');
59
60 const myNodeA = ReactDOM.render(<MyNode />, container);
61 const a = ReactDOM.findDOMNode(myNodeA);
62 expect(a).toBe(null);
63
64 const myNodeB = ReactDOM.render(<MyNode flag={true} />, container);
65 expect(myNodeA === myNodeB).toBe(true);
66
67 const b = ReactDOM.findDOMNode(myNodeB);
68 expect(b.tagName).toBe('SPAN');
69 });
70
71 // @gate www && classic
72 it('findDOMNode should reject random objects', () => {
73 expect(function () {
74 ReactDOM.findDOMNode({foo: 'bar'});
75 }).toThrow('Argument appears to not be a ReactComponent. Keys: foo');
76 });
77
78 // @gate www && classic && !disableLegacyMode
79 it('findDOMNode should reject unmounted objects with render func', () => {
80 class Foo extends React.Component {
81 render() {
82 return <div />;
83 }
84 }
85
86 const container = document.createElement('div');
87 const inst = ReactDOM.render(<Foo />, container);
88 ReactDOM.unmountComponentAtNode(container);
89
90 expect(() => ReactDOM.findDOMNode(inst)).toThrow(
91 'Unable to find node on an unmounted component.',
92 );
93 });
94
95 // @gate www && classic && !disableLegacyMode
96 it('findDOMNode should not throw an error when called within a component that is not mounted', () => {
97 class Bar extends React.Component {
98 UNSAFE_componentWillMount() {
99 expect(ReactDOM.findDOMNode(this)).toBeNull();
100 }
101
102 render() {
103 return <div />;
104 }
105 }
106 expect(() => {
107 const container = document.createElement('div');
108 ReactDOM.render(<Bar />, container);
109 }).not.toThrow();
110 });
111
112 // @gate www && classic && !disableLegacyMode
113 it('findDOMNode should warn if used to find a host component inside StrictMode', () => {
114 let parent = undefined;
115 let child = undefined;
116
117 class ContainsStrictModeChild extends React.Component {
118 render() {
119 return (
120 <StrictMode>
121 <div ref={n => (child = n)} />
122 </StrictMode>
123 );
124 }
125 }
126
127 const container = document.createElement('div');
128 ReactDOM.render(
129 <ContainsStrictModeChild ref={n => (parent = n)} />,
130 container,
131 );
132
133 const match = ReactDOM.findDOMNode(parent);
134 assertConsoleErrorDev([
135 'findDOMNode is deprecated in StrictMode. ' +
136 'findDOMNode was passed an instance of ContainsStrictModeChild which renders StrictMode children. ' +
137 'Instead, add a ref directly to the element you want to reference. ' +
138 'Learn more about using refs safely here: ' +
139 'https://react.dev/link/strict-mode-find-node' +
140 '\n in div (at **)' +
141 '\n in ContainsStrictModeChild (at **)',
142 ]);
143 expect(match).toBe(child);
144 });
145
146 // @gate www && classic && !disableLegacyMode
147 it('findDOMNode should warn if passed a component that is inside StrictMode', () => {
148 let parent = undefined;
149 let child = undefined;
150
151 class IsInStrictMode extends React.Component {
152 render() {
153 return <div ref={n => (child = n)} />;
154 }
155 }
156
157 const container = document.createElement('div');
158
159 ReactDOM.render(
160 <StrictMode>
161 <IsInStrictMode ref={n => (parent = n)} />
162 </StrictMode>,
163 container,
164 );
165
166 const match = ReactDOM.findDOMNode(parent);
167 assertConsoleErrorDev([
168 'findDOMNode is deprecated in StrictMode. ' +
169 'findDOMNode was passed an instance of IsInStrictMode which is inside StrictMode. ' +
170 'Instead, add a ref directly to the element you want to reference. ' +
171 'Learn more about using refs safely here: ' +
172 'https://react.dev/link/strict-mode-find-node' +
173 '\n in div (at **)' +
174 '\n in IsInStrictMode (at **)',
175 ]);
176 expect(match).toBe(child);
177 });
178 });