Skip to content

Commit d3567c5

Browse files
committed
Convert refs-destruction to createRoot
1 parent 64d0c94 commit d3567c5

File tree

1 file changed

+69
-38
lines changed

1 file changed

+69
-38
lines changed

packages/react-dom/src/__tests__/refs-destruction-test.js

Lines changed: 69 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,22 @@
1111

1212
let React;
1313
let ReactDOM;
14+
let ReactDOMClient;
1415
let ReactTestUtils;
15-
1616
let TestComponent;
17+
let act;
18+
let theInnerDivRef;
19+
let theInnerClassComponentRef;
1720

1821
describe('refs-destruction', () => {
1922
beforeEach(() => {
2023
jest.resetModules();
2124

2225
React = require('react');
2326
ReactDOM = require('react-dom');
27+
ReactDOMClient = require('react-dom/client');
2428
ReactTestUtils = require('react-dom/test-utils');
29+
act = require('internal-test-utils').act;
2530

2631
class ClassComponent extends React.Component {
2732
render() {
@@ -30,8 +35,11 @@ describe('refs-destruction', () => {
3035
}
3136

3237
TestComponent = class extends React.Component {
33-
theInnerDivRef = React.createRef();
34-
theInnerClassComponentRef = React.createRef();
38+
constructor(props) {
39+
super(props);
40+
theInnerDivRef = React.createRef();
41+
theInnerClassComponentRef = React.createRef();
42+
}
3543

3644
render() {
3745
if (this.props.destroy) {
@@ -46,77 +54,96 @@ describe('refs-destruction', () => {
4654
} else {
4755
return (
4856
<div>
49-
<div ref={this.theInnerDivRef} />
50-
<ClassComponent ref={this.theInnerClassComponentRef} />
57+
<div ref={theInnerDivRef} />
58+
<ClassComponent ref={theInnerClassComponentRef} />
5159
</div>
5260
);
5361
}
5462
}
5563
};
5664
});
5765

58-
it('should remove refs when destroying the parent', () => {
66+
afterEach(() => {
67+
theInnerClassComponentRef = null;
68+
theInnerDivRef = null;
69+
});
70+
71+
it('should remove refs when destroying the parent', async () => {
5972
const container = document.createElement('div');
60-
const testInstance = ReactDOM.render(<TestComponent />, container);
73+
const root = ReactDOMClient.createRoot(container);
74+
await act(async () => {
75+
root.render(<TestComponent />);
76+
});
6177

62-
expect(
63-
ReactTestUtils.isDOMComponent(testInstance.theInnerDivRef.current),
64-
).toBe(true);
65-
expect(testInstance.theInnerClassComponentRef.current).toBeTruthy();
78+
expect(ReactTestUtils.isDOMComponent(theInnerDivRef.current)).toBe(true);
79+
expect(theInnerClassComponentRef.current).toBeTruthy();
6680

67-
ReactDOM.unmountComponentAtNode(container);
81+
root.unmount();
6882

69-
expect(testInstance.theInnerDivRef.current).toBe(null);
70-
expect(testInstance.theInnerClassComponentRef.current).toBe(null);
83+
expect(theInnerDivRef.current).toBe(null);
84+
expect(theInnerClassComponentRef.current).toBe(null);
7185
});
7286

73-
it('should remove refs when destroying the child', () => {
87+
it('should remove refs when destroying the child', async () => {
7488
const container = document.createElement('div');
75-
const testInstance = ReactDOM.render(<TestComponent />, container);
76-
expect(
77-
ReactTestUtils.isDOMComponent(testInstance.theInnerDivRef.current),
78-
).toBe(true);
79-
expect(testInstance.theInnerClassComponentRef.current).toBeTruthy();
89+
const root = ReactDOMClient.createRoot(container);
90+
await act(async () => {
91+
root.render(<TestComponent />);
92+
});
93+
94+
expect(ReactTestUtils.isDOMComponent(theInnerDivRef.current)).toBe(true);
95+
expect(theInnerClassComponentRef.current).toBeTruthy();
8096

81-
ReactDOM.render(<TestComponent destroy={true} />, container);
97+
await act(async () => {
98+
root.render(<TestComponent destroy={true} />);
99+
});
82100

83-
expect(testInstance.theInnerDivRef.current).toBe(null);
84-
expect(testInstance.theInnerClassComponentRef.current).toBe(null);
101+
expect(theInnerDivRef.current).toBe(null);
102+
expect(theInnerClassComponentRef.current).toBe(null);
85103
});
86104

87-
it('should remove refs when removing the child ref attribute', () => {
105+
it('should remove refs when removing the child ref attribute', async () => {
88106
const container = document.createElement('div');
89-
const testInstance = ReactDOM.render(<TestComponent />, container);
107+
const root = ReactDOMClient.createRoot(container);
108+
await act(async () => {
109+
root.render(<TestComponent />);
110+
});
90111

91-
expect(
92-
ReactTestUtils.isDOMComponent(testInstance.theInnerDivRef.current),
93-
).toBe(true);
94-
expect(testInstance.theInnerClassComponentRef.current).toBeTruthy();
112+
expect(ReactTestUtils.isDOMComponent(theInnerDivRef.current)).toBe(true);
113+
expect(theInnerClassComponentRef.current).toBeTruthy();
95114

96-
ReactDOM.render(<TestComponent removeRef={true} />, container);
115+
await act(async () => {
116+
root.render(<TestComponent removeRef={true} />);
117+
});
97118

98-
expect(testInstance.theInnerDivRef.current).toBe(null);
99-
expect(testInstance.theInnerClassComponentRef.current).toBe(null);
119+
expect(theInnerDivRef.current).toBe(null);
120+
expect(theInnerClassComponentRef.current).toBe(null);
100121
});
101122

102-
it('should not error when destroying child with ref asynchronously', () => {
123+
it('should not error when destroying child with ref asynchronously', async () => {
124+
let nestedRoot;
103125
class Modal extends React.Component {
104126
componentDidMount() {
105127
this.div = document.createElement('div');
128+
nestedRoot = ReactDOMClient.createRoot(this.div);
106129
document.body.appendChild(this.div);
107130
this.componentDidUpdate();
108131
}
109132

110133
componentDidUpdate() {
111-
ReactDOM.render(<div>{this.props.children}</div>, this.div);
134+
setTimeout(() => {
135+
ReactDOM.flushSync(() => {
136+
nestedRoot.render(<div>{this.props.children}</div>);
137+
});
138+
}, 0);
112139
}
113140

114141
componentWillUnmount() {
115142
const self = this;
116143
// some async animation
117144
setTimeout(function () {
118145
expect(function () {
119-
ReactDOM.unmountComponentAtNode(self.div);
146+
nestedRoot.unmount();
120147
}).not.toThrow();
121148
document.body.removeChild(self.div);
122149
}, 0);
@@ -144,8 +171,12 @@ describe('refs-destruction', () => {
144171
}
145172

146173
const container = document.createElement('div');
147-
ReactDOM.render(<App />, container);
148-
ReactDOM.render(<App hidden={true} />, container);
149-
jest.runAllTimers();
174+
const root = ReactDOMClient.createRoot(container);
175+
await act(async () => {
176+
root.render(<App />);
177+
});
178+
await act(async () => {
179+
root.render(<App hidden={true} />);
180+
});
150181
});
151182
});

0 commit comments

Comments
 (0)