Skip to content

Commit ce278d4

Browse files
author
Sebastian Silbermann
committed
fixup! Convert ReactDOMTextarea to createRoot
1 parent 174b420 commit ce278d4

File tree

2 files changed

+201
-2
lines changed

2 files changed

+201
-2
lines changed

packages/react-dom/src/__tests__/ReactDOMTextarea-test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,9 @@ describe('ReactDOMTextarea', () => {
115115
await act(() => {
116116
root.render(<textarea defaultValue="foo" />);
117117
});
118-
119118
await act(() => {
120119
root.render(<textarea defaultValue="bar" />);
121120
});
122-
123121
await act(() => {
124122
root.render(<textarea defaultValue="noise" />);
125123
});
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
// jscodeshift can take a parser, like "babel", "babylon", "flow", "ts", or "tsx"
2+
// Read more: https://github.com/facebook/jscodeshift#parser
3+
export const parser = 'flow';
4+
5+
// Press ctrl+space for code completion
6+
export default function transformer(file, api) {
7+
const j = api.jscodeshift;
8+
9+
return j(file.source)
10+
.find(j.ExpressionStatement)
11+
.forEach(path => {
12+
const {
13+
node: {
14+
expression: {callee},
15+
},
16+
} = path;
17+
18+
if (
19+
callee !== undefined &&
20+
callee.type === 'MemberExpression' &&
21+
callee.object.type === 'Identifier' &&
22+
callee.object.name === 'ReactDOM' &&
23+
callee.property.type === 'Identifier' &&
24+
callee.property.name === 'render'
25+
) {
26+
// replace ReactDOM.render with
27+
// const root = ReactDOMClient.createRoot(container);
28+
// await act(() => { root.render() })
29+
const [element, container] = path.node.expression.arguments;
30+
j(path).insertBefore([
31+
j.variableDeclaration('const', [
32+
j.variableDeclarator(
33+
j.identifier('root'),
34+
j.callExpression(
35+
j.memberExpression(
36+
j.identifier('ReactDOMClient'),
37+
j.identifier('createRoot'),
38+
),
39+
[container],
40+
),
41+
),
42+
]),
43+
]);
44+
j(path).replaceWith(
45+
j.expressionStatement(
46+
j.awaitExpression(
47+
j.callExpression(j.identifier('act'), [
48+
j.arrowFunctionExpression(
49+
[],
50+
j.blockStatement([
51+
j.expressionStatement(
52+
j.callExpression(
53+
j.memberExpression(
54+
j.identifier('root'),
55+
j.identifier('render'),
56+
),
57+
[element],
58+
),
59+
),
60+
]),
61+
),
62+
]),
63+
),
64+
),
65+
);
66+
67+
path.parent.parent.value.async = true;
68+
} else if (
69+
callee !== undefined &&
70+
callee.type === 'MemberExpression' &&
71+
callee.object.type === 'Identifier' &&
72+
callee.object.name === 'ReactTestUtils' &&
73+
callee.property.type === 'Identifier' &&
74+
callee.property.name === 'renderIntoDocument'
75+
) {
76+
// replace ReactTestUtils.renderIntoDocument with
77+
// const container = document.createElement('div')
78+
// const root = ReactDOMClient.createRoot(container);
79+
// await act(() => { root.render() })
80+
const [element] = path.node.expression.arguments;
81+
j(path).insertBefore([
82+
j.variableDeclaration('const', [
83+
j.variableDeclarator(
84+
j.identifier('container'),
85+
j.callExpression(j.identifier('document.createElement'), [
86+
j.literal('div'),
87+
]),
88+
),
89+
]),
90+
j.variableDeclaration('const', [
91+
j.variableDeclarator(
92+
j.identifier('root'),
93+
j.callExpression(
94+
j.memberExpression(
95+
j.identifier('ReactDOMClient'),
96+
j.identifier('createRoot'),
97+
),
98+
[j.identifier('container')],
99+
),
100+
),
101+
]),
102+
]);
103+
j(path).replaceWith(
104+
j.expressionStatement(
105+
j.awaitExpression(
106+
j.callExpression(j.identifier('act'), [
107+
j.arrowFunctionExpression(
108+
[],
109+
j.blockStatement([
110+
j.expressionStatement(
111+
j.callExpression(
112+
j.memberExpression(
113+
j.identifier('root'),
114+
j.identifier('render'),
115+
),
116+
[element],
117+
),
118+
),
119+
]),
120+
),
121+
]),
122+
),
123+
),
124+
);
125+
126+
path.parent.parent.value.async = true;
127+
}
128+
})
129+
.find(j.VariableDeclaration)
130+
.forEach(path => {
131+
const {
132+
node: {declarations},
133+
} = path;
134+
if (
135+
declarations.length === 1 &&
136+
declarations[0].init !== null &&
137+
declarations[0].init.type === 'CallExpression'
138+
) {
139+
const {arguments: args, callee} = declarations[0].init;
140+
if (
141+
callee !== undefined &&
142+
callee.type === 'MemberExpression' &&
143+
callee.object.type === 'Identifier' &&
144+
callee.object.name === 'ReactDOM' &&
145+
callee.property.type === 'Identifier' &&
146+
callee.property.name === 'render'
147+
) {
148+
// replace const node = ReactDOM.render(element, container) with
149+
// const root = ReactDOMClient.createRoot(container);
150+
// await act(() => { root.render() })
151+
// const node = container.firstChild;
152+
const [element, container] = args;
153+
j(path).insertBefore([
154+
j.variableDeclaration('const', [
155+
j.variableDeclarator(
156+
j.identifier('root'),
157+
j.callExpression(
158+
j.memberExpression(
159+
j.identifier('ReactDOMClient'),
160+
j.identifier('createRoot'),
161+
),
162+
[container],
163+
),
164+
),
165+
]),
166+
j.expressionStatement(
167+
j.awaitExpression(
168+
j.callExpression(j.identifier('act'), [
169+
j.arrowFunctionExpression(
170+
[],
171+
j.blockStatement([
172+
j.expressionStatement(
173+
j.callExpression(
174+
j.memberExpression(
175+
j.identifier('root'),
176+
j.identifier('render'),
177+
),
178+
[element],
179+
),
180+
),
181+
]),
182+
),
183+
]),
184+
),
185+
),
186+
]);
187+
j(path).replaceWith(
188+
j.variableDeclaration('const', [
189+
j.variableDeclarator(
190+
j.identifier(declarations[0].id.name),
191+
j.identifier('container.firstChild'),
192+
),
193+
]),
194+
);
195+
196+
path.parent.parent.value.async = true;
197+
}
198+
}
199+
})
200+
.toSource();
201+
}

0 commit comments

Comments
 (0)