-
Notifications
You must be signed in to change notification settings - Fork 48.1k
/
Copy pathReactDOMServerIntegrationRefs-test.js
131 lines (114 loc) · 3.64 KB
/
ReactDOMServerIntegrationRefs-test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
*/
'use strict';
const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils');
let React;
let ReactDOMClient;
let ReactDOMServer;
let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModules();
React = require('react');
ReactDOMClient = require('react-dom/client');
ReactDOMServer = require('react-dom/server');
ReactTestUtils = require('react-dom/test-utils');
// Make them available to the helpers.
return {
ReactDOMClient,
ReactDOMServer,
ReactTestUtils,
};
}
const {
resetModules,
asyncReactDOMRender,
clientRenderOnServerString,
expectMarkupMatch,
} = ReactDOMServerIntegrationUtils(initModules);
describe('ReactDOMServerIntegration', () => {
beforeEach(() => {
resetModules();
});
describe('refs', function () {
it('should not run ref code on server', async () => {
let refCount = 0;
class RefsComponent extends React.Component {
render() {
return <div ref={e => refCount++} />;
}
}
await expectMarkupMatch(<RefsComponent />, <div />);
expect(refCount).toBe(0);
});
it('should run ref code on client', async () => {
let refCount = 0;
class RefsComponent extends React.Component {
render() {
return <div ref={e => refCount++} />;
}
}
await expectMarkupMatch(<div />, <RefsComponent />);
expect(refCount).toBe(1);
});
it('should send the correct element to ref functions on client', async () => {
let refElement = null;
class RefsComponent extends React.Component {
render() {
return <div ref={e => (refElement = e)} />;
}
}
const e = await clientRenderOnServerString(<RefsComponent />);
expect(refElement).not.toBe(null);
expect(refElement).toBe(e);
});
it('should have string refs on client when rendered over server markup', async () => {
class RefsComponent extends React.Component {
render() {
return <div ref="myDiv" />;
}
}
const markup = ReactDOMServer.renderToString(<RefsComponent />);
const root = document.createElement('div');
root.innerHTML = markup;
let component = null;
resetModules();
await expect(async () => {
await asyncReactDOMRender(
<RefsComponent ref={e => (component = e)} />,
root,
true,
);
}).toErrorDev([
'Warning: Component "RefsComponent" contains the string ref "myDiv". ' +
'Support for string refs will be removed in a future major release. ' +
'We recommend using useRef() or createRef() instead. ' +
'Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref\n' +
' in RefsComponent (at **)',
]);
expect(component.refs.myDiv).toBe(root.firstChild);
});
});
it('should forward refs', async () => {
const divRef = React.createRef();
class InnerComponent extends React.Component {
render() {
return <div ref={this.props.forwardedRef}>{this.props.value}</div>;
}
}
const OuterComponent = React.forwardRef((props, ref) => (
<InnerComponent {...props} forwardedRef={ref} />
));
await clientRenderOnServerString(
<OuterComponent ref={divRef} value="hello" />,
);
expect(divRef.current).not.toBe(null);
expect(divRef.current.textContent).toBe('hello');
});
});