Skip to content

Commit 4af46e5

Browse files
committed
[18] Switch code samples to createRoot (#4470)
* [18] Switch code samples to createRoot * Feedback fixes * Feedback updates
1 parent 2610a05 commit 4af46e5

27 files changed

+108
-188
lines changed

beta/src/pages/learn/add-react-to-a-website.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,12 @@ function LikeButton() {
7474

7575
### Step 4: Add your React Component to the page {/*step-4-add-your-react-component-to-the-page*/}
7676

77-
Lastly, add two lines to the bottom of **like_button.js**. These two lines of code find the `<div>` you added to your HTML in the first step and then display the "Like" button React component inside of it.
77+
Lastly, add three lines to the bottom of **like_button.js**. These three lines of code find the `<div>` you added to your HTML in the first step, create a React app with it, and then display the "Like" button React component inside of it.
7878

7979
```js
8080
const domContainer = document.getElementById('component-goes-here');
81-
ReactDOM.render(React.createElement(LikeButton), domContainer);
81+
const root = ReactDOM.createRoot(domContainer);
82+
root.render(React.createElement(LikeButton));
8283
```
8384

8485
**Congratulations! You have just rendered your first React component to your website!**
@@ -88,21 +89,21 @@ ReactDOM.render(React.createElement(LikeButton), domContainer);
8889

8990
#### You can reuse components! {/*you-can-reuse-components*/}
9091

91-
You might want to display a React component in multiple places on the same HTML page. This is most useful while React-powered parts of the page are isolated from each other. You can do this by calling `ReactDOM.render()` multiple times with multiple container elements.
92+
You might want to display a React component in multiple places on the same HTML page. This is most useful while React-powered parts of the page are isolated from each other. You can do this by calling `ReactDOM.createRoot()` multiple times with multiple container elements.
9293

9394
1. In **index.html**, add an additional container element `<div id="component-goes-here-too"></div>`.
9495
2. In **like_button.js**, add an additional `ReactDOM.render()` for the new container element:
9596

9697
```js {6,7,8,9}
97-
ReactDOM.render(
98-
React.createElement(LikeButton),
98+
const root1 = ReactDOM.createRoot(
9999
document.getElementById('component-goes-here')
100100
);
101+
root1.render(React.createElement(LikeButton));
101102

102-
ReactDOM.render(
103-
React.createElement(LikeButton),
103+
const root2 = ReactDOM.createRoot(
104104
document.getElementById('component-goes-here-too')
105105
);
106+
root2.render(React.createElement(LikeButton));
106107
```
107108

108109
Check out [an example that displays the "Like" button three times and passes some data to it](https://gist.github.com/rachelnabors/c0ea05cc33fbe75ad9bbf78e9044d7f8)!
@@ -157,8 +158,8 @@ Now you can use JSX in any `<script>` tag by adding `type="text/babel"` attribut
157158

158159
```jsx {1}
159160
<script type="text/babel">
160-
ReactDOM.render(
161-
<h1>Hello, world!</h1>, document.getElementById('root') );
161+
const root = ReactDOM.createRoot(document.getElementById('root'));
162+
root.render(<h1>Hello, world!</h1>);
162163
</script>
163164
```
164165

content/docs/add-react-to-a-website.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,15 @@ Open **[this starter code](https://gist.github.com/gaearon/0b180827c190fe4fd98b4
7777
7878
After **[the starter code](https://gist.github.com/gaearon/0b180827c190fe4fd98b4c7f570ea4a8/raw/b9157ce933c79a4559d2aa9ff3372668cce48de7/LikeButton.js)**, add two lines to the bottom of `like_button.js`:
7979

80-
```js{3,4}
80+
```js{3,4,5}
8181
// ... the starter code you pasted ...
8282
8383
const domContainer = document.querySelector('#like_button_container');
84-
ReactDOM.render(e(LikeButton), domContainer);
84+
const root = ReactDOM.createRoot(domContainer);
85+
root.render(e(LikeButton));
8586
```
8687

87-
These two lines of code find the `<div>` we added to our HTML in the first step, and then display our "Like" button React component inside of it.
88+
These three lines of code find the `<div>` we added to our HTML in the first step, create a React app with it, and then display our "Like" button React component inside of it.
8889

8990
### That's It! {#thats-it}
9091

content/docs/addons-shallow-renderer.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ Shallow testing currently has some limitations, namely not supporting refs.
5959

6060
You can think of the shallowRenderer as a "place" to render the component you're testing, and from which you can extract the component's output.
6161

62-
`shallowRenderer.render()` is similar to [`ReactDOM.render()`](/docs/react-dom.html#render) but it doesn't require DOM and only renders a single level deep. This means you can test components isolated from how their children are implemented.
62+
`shallowRenderer.render()` is similar to [`root.render()`](/docs/react-dom-client.html#createroot) but it doesn't require DOM and only renders a single level deep. This means you can test components isolated from how their children are implemented.
6363

6464
### `shallowRenderer.getRenderOutput()` {#shallowrenderergetrenderoutput}
6565

content/docs/addons-test-utils.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ Here is how we can test it:
8989

9090
```js{3,20-22,29-31}
9191
import React from 'react';
92-
import ReactDOM from 'react-dom';
92+
import ReactDOM from 'react-dom/client';
9393
import { act } from 'react-dom/test-utils';
9494
import Counter from './Counter';
9595
@@ -108,7 +108,7 @@ afterEach(() => {
108108
it('can render and update a counter', () => {
109109
// Test first render and componentDidMount
110110
act(() => {
111-
ReactDOM.render(<Counter />, container);
111+
ReactDOM.createRoot(container).render(<Counter />);
112112
});
113113
const button = container.querySelector('button');
114114
const label = container.querySelector('p');
@@ -304,7 +304,7 @@ Render a React element into a detached DOM node in the document. **This function
304304

305305
```js
306306
const domContainer = document.createElement('div');
307-
ReactDOM.render(element, domContainer);
307+
ReactDOM.createRoot(domContainer).render(element);
308308
```
309309

310310
> Note:

content/docs/components-and-props.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,15 @@ function Welcome(props) {
7070
}
7171
7272
const element = <Welcome name="Sara" />;
73-
ReactDOM.render(
74-
element,
75-
document.getElementById('root')
76-
);
73+
const root = ReactDOM.createRoot(document.getElementById('root'));
74+
root.render(element);
7775
```
7876

7977
**[Try it on CodePen](https://codepen.io/gaearon/pen/YGYmEG?editors=1010)**
8078

8179
Let's recap what happens in this example:
8280

83-
1. We call `ReactDOM.render()` with the `<Welcome name="Sara" />` element.
81+
1. We call `root.render()` with the `<Welcome name="Sara" />` element.
8482
2. React calls the `Welcome` component with `{name: 'Sara'}` as the props.
8583
3. Our `Welcome` component returns a `<h1>Hello, Sara</h1>` element as the result.
8684
4. React DOM efficiently updates the DOM to match `<h1>Hello, Sara</h1>`.
@@ -111,11 +109,6 @@ function App() {
111109
</div>
112110
);
113111
}
114-
115-
ReactDOM.render(
116-
<App />,
117-
document.getElementById('root')
118-
);
119112
```
120113

121114
**[Try it on CodePen](https://codepen.io/gaearon/pen/KgQKPr?editors=1010)**

content/docs/concurrent-mode-adoption.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ import ReactDOM from 'react-dom';
7474
//
7575
// You can opt into Concurrent Mode by writing:
7676

77-
ReactDOM.unstable_createRoot(
77+
ReactDOM.createRoot(
7878
document.getElementById('root')
7979
).render(<App />);
8080
```

content/docs/forms.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,10 @@ Specifying the `value` prop on a [controlled component](/docs/forms.html#control
275275
The following code demonstrates this. (The input is locked at first but becomes editable after a short delay.)
276276

277277
```javascript
278-
ReactDOM.render(<input value="hi" />, mountNode);
278+
ReactDOM.createRoot(mountNode).render(<input value="hi" />);
279279

280280
setTimeout(function() {
281-
ReactDOM.render(<input value={null} />, mountNode);
281+
ReactDOM.createRoot(mountNode).render(<input value={null} />);
282282
}, 1000);
283283

284284
```

content/docs/handling-events.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,6 @@ class Toggle extends React.Component {
8484
);
8585
}
8686
}
87-
88-
ReactDOM.render(
89-
<Toggle />,
90-
document.getElementById('root')
91-
);
9287
```
9388

9489
[**Try it on CodePen**](https://codepen.io/gaearon/pen/xEmzGg?editors=0010)

content/docs/hello-world.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ next: introducing-jsx.html
88

99
The smallest React example looks like this:
1010

11-
```js
12-
ReactDOM.render(
13-
<h1>Hello, world!</h1>,
14-
document.getElementById('root')
15-
);
11+
```jsx
12+
ReactDOM
13+
.createRoot(document.getElementById('root'))
14+
.render(<h1>Hello, world!</h1>);
1615
```
1716

1817
It displays a heading saying "Hello, world!" on the page.

content/docs/hooks-faq.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ We'll test it using React DOM. To make sure that the behavior matches what happe
148148

149149
```js{3,20-22,29-31}
150150
import React from 'react';
151-
import ReactDOM from 'react-dom';
151+
import ReactDOM from 'react-dom/client';
152152
import { act } from 'react-dom/test-utils';
153153
import Counter from './Counter';
154154
@@ -167,7 +167,7 @@ afterEach(() => {
167167
it('can render and update a counter', () => {
168168
// Test first render and effect
169169
act(() => {
170-
ReactDOM.render(<Counter />, container);
170+
ReactDOM.createRoot(container).render(<Counter />);
171171
});
172172
const button = container.querySelector('button');
173173
const label = container.querySelector('p');

content/docs/implementation-notes.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ The reconciler itself doesn't have a public API. [Renderers](/docs/codebase-over
3232
Let's consider the first time you mount a component:
3333

3434
```js
35-
ReactDOM.render(<App />, rootEl);
35+
const root = ReactDOM.createRoot(rootEl);
36+
root.render(<App />);
3637
```
3738

38-
React DOM will pass `<App />` along to the reconciler. Remember that `<App />` is a React element, that is, a description of *what* to render. You can think about it as a plain object:
39+
`root.render` will pass `<App />` along to the reconciler. Remember that `<App />` is a React element, that is, a description of *what* to render. You can think about it as a plain object:
3940

4041
```js
4142
console.log(<App />);
@@ -236,9 +237,9 @@ This is working but still far from how the reconciler is really implemented. The
236237
The key feature of React is that you can re-render everything, and it won't recreate the DOM or reset the state:
237238

238239
```js
239-
ReactDOM.render(<App />, rootEl);
240+
root.render(<App />);
240241
// Should reuse the existing DOM:
241-
ReactDOM.render(<App />, rootEl);
242+
root.render(<App />);
242243
```
243244

244245
However, our implementation above only knows how to mount the initial tree. It can't perform updates on it because it doesn't store all the necessary information, such as all the `publicInstance`s, or which DOM `node`s correspond to which components.
@@ -412,7 +413,7 @@ If you're struggling to imagine how an internal instance tree is structured in m
412413

413414
<img src="../images/docs/implementation-notes-tree.png" width="500" style="max-width: 100%" alt="React DevTools tree" />
414415

415-
To complete this refactoring, we will introduce a function that mounts a complete tree into a container node, just like `ReactDOM.render()`. It returns a public instance, also like `ReactDOM.render()`:
416+
To complete this refactoring, we will introduce a function that mounts a complete tree into a container node and a public instance:
416417

417418
```js
418419
function mountTree(element, containerNode) {

content/docs/integrating-with-other-libraries.md

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,9 @@ class Chosen extends React.Component {
190190

191191
## Integrating with Other View Libraries {#integrating-with-other-view-libraries}
192192

193-
React can be embedded into other applications thanks to the flexibility of [`ReactDOM.render()`](/docs/react-dom.html#render).
193+
React can be embedded into other applications thanks to the flexibility of [`createRoot()`](/docs/react-dom-client.html#createRoot).
194194

195-
Although React is commonly used at startup to load a single root React component into the DOM, `ReactDOM.render()` can also be called multiple times for independent parts of the UI which can be as small as a button, or as large as an app.
195+
Although React is commonly used at startup to load a single root React component into the DOM, `root.render()` can also be called multiple times for independent parts of the UI which can be as small as a button, or as large as an app.
196196

197197
In fact, this is exactly how React is used at Facebook. This lets us write applications in React piece by piece, and combine them with our existing server-generated templates and other client-side code.
198198

@@ -216,15 +216,9 @@ function Button() {
216216
return <button id="btn">Say Hello</button>;
217217
}
218218

219-
ReactDOM.render(
220-
<Button />,
221-
document.getElementById('container'),
222-
function() {
223-
$('#btn').click(function() {
224-
alert('Hello!');
225-
});
226-
}
227-
);
219+
$('#btn').click(function() {
220+
alert('Hello!');
221+
});
228222
```
229223

230224
From here you could start moving more logic into the component and begin adopting more common React practices. For example, in components it is best not to rely on IDs because the same component can be rendered multiple times. Instead, we will use the [React event system](/docs/handling-events.html) and register the click handler directly on the React `<button>` element:
@@ -240,44 +234,40 @@ function HelloButton() {
240234
}
241235
return <Button onClick={handleClick} />;
242236
}
243-
244-
ReactDOM.render(
245-
<HelloButton />,
246-
document.getElementById('container')
247-
);
248237
```
249238

250239
[**Try it on CodePen**](https://codepen.io/gaearon/pen/RVKbvW?editors=1010)
251240

252-
You can have as many such isolated components as you like, and use `ReactDOM.render()` to render them to different DOM containers. Gradually, as you convert more of your app to React, you will be able to combine them into larger components, and move some of the `ReactDOM.render()` calls up the hierarchy.
241+
You can have as many such isolated components as you like, and use `ReactDOM.createRoot()` to render them to different DOM containers. Gradually, as you convert more of your app to React, you will be able to combine them into larger components, and move some of the `ReactDOM.createRoot()` calls up the hierarchy.
253242

254243
### Embedding React in a Backbone View {#embedding-react-in-a-backbone-view}
255244

256245
[Backbone](https://backbonejs.org/) views typically use HTML strings, or string-producing template functions, to create the content for their DOM elements. This process, too, can be replaced with rendering a React component.
257246

258-
Below, we will create a Backbone view called `ParagraphView`. It will override Backbone's `render()` function to render a React `<Paragraph>` component into the DOM element provided by Backbone (`this.el`). Here, too, we are using [`ReactDOM.render()`](/docs/react-dom.html#render):
247+
Below, we will create a Backbone view called `ParagraphView`. It will override Backbone's `render()` function to render a React `<Paragraph>` component into the DOM element provided by Backbone (`this.el`). Here, too, we are using [`ReactDOM.createRoot()`](/docs/react-dom-client.html#createroot):
259248

260-
```js{1,5,8,12}
249+
```js{1,5,8-9,13}
261250
function Paragraph(props) {
262251
return <p>{props.text}</p>;
263252
}
264253
265254
const ParagraphView = Backbone.View.extend({
266255
render() {
267256
const text = this.model.get('text');
268-
ReactDOM.render(<Paragraph text={text} />, this.el);
257+
this.root = ReactDOM.createRoot(this.el);
258+
this.root.render(<Paragraph text={text} />);
269259
return this;
270260
},
271261
remove() {
272-
ReactDOM.unmountComponentAtNode(this.el);
262+
this.root.unmount();
273263
Backbone.View.prototype.remove.call(this);
274264
}
275265
});
276266
```
277267

278268
[**Try it on CodePen**](https://codepen.io/gaearon/pen/gWgOYL?editors=0010)
279269

280-
It is important that we also call `ReactDOM.unmountComponentAtNode()` in the `remove` method so that React unregisters event handlers and other resources associated with the component tree when it is detached.
270+
It is important that we also call `root.unmount()` in the `remove` method so that React unregisters event handlers and other resources associated with the component tree when it is detached.
281271

282272
When a component is removed *from within* a React tree, the cleanup is performed automatically, but because we are removing the entire tree by hand, we must call this method.
283273

@@ -428,10 +418,8 @@ function Example(props) {
428418
}
429419
430420
const model = new Backbone.Model({ firstName: 'Frodo' });
431-
ReactDOM.render(
432-
<Example model={model} />,
433-
document.getElementById('root')
434-
);
421+
const root = ReactDOM.createRoot(document.getElementById('root'));
422+
root.render(<Example model={model} />);
435423
```
436424

437425
[**Try it on CodePen**](https://codepen.io/gaearon/pen/PmWwwa?editors=0010)

content/docs/introducing-jsx.md

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,6 @@ In the example below, we declare a variable called `name` and then use it inside
3535
```js{1,2}
3636
const name = 'Josh Perez';
3737
const element = <h1>Hello, {name}</h1>;
38-
39-
ReactDOM.render(
40-
element,
41-
document.getElementById('root')
42-
);
4338
```
4439

4540
You can put any valid [JavaScript expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions) inside the curly braces in JSX. For example, `2 + 2`, `user.firstName`, or `formatName(user)` are all valid JavaScript expressions.
@@ -61,11 +56,6 @@ const element = (
6156
Hello, {formatName(user)}!
6257
</h1>
6358
);
64-
65-
ReactDOM.render(
66-
element,
67-
document.getElementById('root')
68-
);
6959
```
7060

7161
**[Try it on CodePen](https://codepen.io/gaearon/pen/PGEjdG?editors=1010)**

0 commit comments

Comments
 (0)