Skip to content

Commit 4f01e35

Browse files
committed
Rewrite some component doc parts
1 parent 6fe2302 commit 4f01e35

File tree

1 file changed

+82
-41
lines changed

1 file changed

+82
-41
lines changed

content/docs/reference-react-component.md

Lines changed: 82 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,61 +15,83 @@ redirect_from:
1515
- "tips/use-react-with-other-libraries.html"
1616
---
1717

18-
[Components](/docs/components-and-props.html) let you split the UI into independent, reusable pieces, and think about each piece in isolation. `React.Component` is provided by [`React`](/docs/react-api.html).
18+
[Components](/docs/components-and-props.html) let you split the UI into independent, reusable pieces, and think about each piece in isolation. React provides a `React.Component` base class to let you define encapsulated components that may contain [local state and handle lifecycle events](/docs/state-and-lifecycle.html).
1919

2020
## Overview
2121

22-
`React.Component` is an abstract base class, so it rarely makes sense to refer to `React.Component` directly. Instead, you will typically subclass it, and define at least a [`render()`](#render) method.
22+
React provides two ways to define components. For very simple components that just render something based on their props, you can use a function:
2323

24-
Normally you would define a React component as a plain [JavaScript class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes):
24+
```js
25+
function Welcome(props) {
26+
return <h1>Hello, {props.name}</h1>;
27+
}
28+
```
2529

26-
```javascript
27-
class Greeting extends React.Component {
30+
In the example above, we didn't use `React.Component`.
31+
32+
However, sometimes you need to keep some local state in the component, or run some code when it is created, updated, or removed from the DOM. For those cases, you can declare it as a [JavaScript class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes) that extends `React.Component`:
33+
34+
```js
35+
class Welcome extends React.Component {
2836
render() {
2937
return <h1>Hello, {this.props.name}</h1>;
3038
}
3139
}
3240
```
3341

34-
If you don't use ES6 yet, you may use the `create-react-class` module instead. Take a look at [Using React without ES6](/docs/react-without-es6.html) to learn more.
42+
The above two component definitions are equivalent, but currently class components have access to more features. They are described below. The only method you *must* define in a `React.Component` subclass is called [`render()`](#render), the rest are optional.
43+
44+
>Note:
45+
>
46+
>React doesn't force you to use the ES6 class syntax. If you prefer to avoid it, you may use the `create-react-class` module or a similar custom abstraction instead. Take a look at [Using React without ES6](/docs/react-without-es6.html) to learn more.
47+
48+
### Avoid Custom Base Classes
49+
50+
**We strongly recommend against creating your own base component classes, both in the application and the library code.**
51+
52+
In React components, code reuse is primarily achieved through composition rather than inheritance. Take a look at [these common scenarios](/docs/composition-vs-inheritance.html) to get a feel for how to use composition.
3553

36-
Note that **we don't recommend creating your own base component classes**. Code reuse is primarily achieved through composition rather than inheritance in React. Take a look at [these common scenarios](/docs/composition-vs-inheritance.html) to get a feel for how to use composition.
54+
Avoid creating and extending custom base component classes.
3755

3856
### The Component Lifecycle
3957

4058
Each component has several "lifecycle methods" that you can override to run code at particular times in the process.
4159

42-
**You can use [interactive lifecycle diagram](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/) as a cheat sheet.**
60+
**You can use [this interactive lifecycle diagram](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/) as a cheat sheet.**
4361

44-
In the list below, commonly used lifecycle methods are marked as **bold**. The rest of them exists for relatively rare use cases.
62+
In the list below, commonly used lifecycle methods are marked as **bold**. The rest of them exist for relatively rare use cases.
4563

4664
#### Mounting
4765

48-
These methods are called when an instance of a component is being created and inserted into the DOM:
66+
These methods are called in the following order when an instance of a component is being created and inserted into the DOM:
4967

5068
- [**`constructor()`**](#constructor)
5169
- [`static getDerivedStateFromProps()`](#static-getderivedstatefromprops)
5270
- [**`render()`**](#render)
5371
- [**`componentDidMount()`**](#componentdidmount)
5472

55-
These methods are considered legacy and you should [avoid them](/blog/2018/03/27/update-on-async-rendering.html) in new code:
56-
57-
- [`componentWillMount()` / `UNSAFE_componentWillMount()`](#unsafe_componentwillmount)
73+
>Note:
74+
>
75+
>These methods are considered legacy and you should [avoid them](/blog/2018/03/27/update-on-async-rendering.html) in new code:
76+
>
77+
>- [`componentWillMount()` / `UNSAFE_componentWillMount()`](#unsafe_componentwillmount)
5878
5979
#### Updating
6080

61-
An update can be caused by changes to props or state. These methods are called when a component is being re-rendered:
81+
An update can be caused by changes to props or state. These methods are called in the following order when a component is being re-rendered:
6282

6383
- [`static getDerivedStateFromProps()`](#static-getderivedstatefromprops)
6484
- [`shouldComponentUpdate()`](#shouldcomponentupdate)
6585
- [**`render()`**](#render)
6686
- [`getSnapshotBeforeUpdate()`](#getsnapshotbeforeupdate)
6787
- [**`componentDidUpdate()`**](#componentdidupdate)
6888

69-
These methods are considered legacy and you should [avoid them](/blog/2018/03/27/update-on-async-rendering.html) in new code:
70-
71-
- [`componentWillUpdate()` / `UNSAFE_componentWillUpdate()`](#unsafe_componentwillupdate)
72-
- [`componentWillReceiveProps()` / `UNSAFE_componentWillReceiveProps()`](#unsafe_componentwillreceiveprops)
89+
>Note:
90+
>
91+
>These methods are considered legacy and you should [avoid them](/blog/2018/03/27/update-on-async-rendering.html) in new code:
92+
>
93+
>- [`componentWillUpdate()` / `UNSAFE_componentWillUpdate()`](#unsafe_componentwillupdate)
94+
>- [`componentWillReceiveProps()` / `UNSAFE_componentWillReceiveProps()`](#unsafe_componentwillreceiveprops)
7395
7496
#### Unmounting
7597

@@ -106,17 +128,17 @@ Each component also provides some other APIs:
106128

107129
### Commonly Used Lifecycle Methods
108130

109-
The methods in this section are used most often. The vast majority of your components shouldn't need to implement any other lifecycle methods.
131+
The methods in this section cover the vast majority of use cases you'll encounter creating React components.
110132

111-
**You can see them all on this [interactive lifecycle diagram](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/).**
133+
**For a visual reference, check out [this interactive lifecycle diagram](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/).**
112134

113135
### `render()`
114136

115137
```javascript
116138
render()
117139
```
118140

119-
The `render()` method is required.
141+
The `render()` method is the only required method in a class component.
120142

121143
When called, it should examine `this.props` and `this.state` and return one of the following types:
122144

@@ -146,11 +168,27 @@ constructor(props)
146168

147169
The constructor for a React component is called before it is mounted. When implementing the constructor for a `React.Component` subclass, you should call `super(props)` before any other statement. Otherwise, `this.props` will be undefined in the constructor, which can lead to bugs.
148170

149-
Avoid introducing any side-effects or subscriptions in the constructor. For those use cases, use `componentDidMount()` instead.
171+
Typically, in React constructors are only used for two purposes:
150172

151-
The constructor is the right place to initialize state. To do so, just assign an object to `this.state`; don't try to call `setState()` from the constructor. The constructor is also often used to bind event handlers to the class instance.
173+
* Initializing [local state](/docs/state-and-lifecycle.html) by assigning an object to `this.state`.
174+
* Binding [event handler](/docs/handling-events.html) methods to an instance.
152175

153-
>Note:
176+
You **should not call `setState()`** in the `constructor()`. Instead, if your component needs to use local state, **assign the initial state to `this.state`** directly in the constructor:
177+
178+
```js
179+
constructor(props) {
180+
super(props);
181+
// Don't call this.setState() here!
182+
this.state = { counter: 0 };
183+
this.handleClick = this.handleClick.bind(this);
184+
}
185+
```
186+
187+
Constructor is the only place where you should assign `this.state` directly. In all other methods, you need to use `this.setState()` instead.
188+
189+
Avoid introducing any side-effects or subscriptions in the constructor. For those use cases, use `componentDidMount()` instead.
190+
191+
>Note
154192
>
155193
>**Avoid copying props into state! This is a common mistake:**
156194
>
@@ -177,11 +215,11 @@ The constructor is the right place to initialize state. To do so, just assign an
177215
componentDidMount()
178216
```
179217
180-
`componentDidMount()` is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
218+
`componentDidMount()` is invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
181219

182220
This method is a good place to set up any subscriptions. If you do that, don't forget to unsubscribe in `componentWillUnmount()`.
183221

184-
Calling `setState()` in this method will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the `render()` will be called twice in this case, the user won't see the intermediate state. Use this pattern with caution because it often causes performance issues. It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position.
222+
You **may call `setState()`** in `componentDidMount()`. It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the `render()` will be called twice in this case, the user won't see the intermediate state. Use this pattern with caution because it often causes performance issues. In most cases, you should be able to assign the initial state in the `constructor()` instead. It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position.
185223

186224
* * *
187225

@@ -202,10 +240,11 @@ componentDidUpdate(prevProps) {
202240
this.fetchData(this.props.userID);
203241
}
204242
}
205-
206243
```
207244

208-
If your component implements the `getSnapshotBeforeUpdate()` lifecycle, the value it returns will be passed as a third "snapshot" parameter to `componentDidUpdate()`. (Otherwise this parameter will be undefined.)
245+
You **may call `setState()`** in `componentDidUpdate()` but note that **it must be wrapped in a condition** like in the example above, or you'll cause an infinite loop. It would also cause an extra re-rendering which, while not visible to the user, can affect the component performance. If you're trying to "mirror" some state to a prop coming from above, consider using the prop directly instead. Read more about [why copying props into state causes bugs](/blog/2018/06/07/you-probably-dont-need-derived-state.html).
246+
247+
If your component implements the `getSnapshotBeforeUpdate()` lifecycle (which is rare), the value it returns will be passed as a third "snapshot" parameter to `componentDidUpdate()`. Otherwise this parameter will be undefined.
209248

210249
> Note
211250
>
@@ -219,15 +258,17 @@ If your component implements the `getSnapshotBeforeUpdate()` lifecycle, the valu
219258
componentWillUnmount()
220259
```
221260

222-
`componentWillUnmount()` is invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in `componentDidMount()`. You should not call `setState()` here because the component will never be re-rendered.
261+
`componentWillUnmount()` is invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in `componentDidMount()`.
262+
263+
You **should not call `setState()`** in `componentWillUnmount()` because the component will never be re-rendered. Once a component instance is unmounted, it will never be mounted again.
223264

224265
* * *
225266

226267
### Rarely Used Lifecycle Methods
227268

228269
The methods in this section correspond to uncommon use cases. They're handy once in a while, but most of your components probably don't need any of them.
229270

230-
**You can see most of them on this [interactive lifecycle diagram](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/) if you click the "Show less common lifecycles" checkbox at the top.**
271+
**You can see most of the methods below on [this interactive lifecycle diagram](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/) if you click the "Show less common lifecycles" checkbox at the top of it.**
231272

232273

233274
### `shouldComponentUpdate()`
@@ -238,20 +279,18 @@ shouldComponentUpdate(nextProps, nextState)
238279

239280
Use `shouldComponentUpdate()` to let React know if a component's output is not affected by the current change in state or props. The default behavior is to re-render on every state change, and in the vast majority of cases you should rely on the default behavior.
240281

241-
**Don't add `shouldComponentUpdate()` to a component unless you have a specific performance problem, and [profiling](/docs/optimizing-performance.html) demonstrates that it solves your problem.**
242-
243-
**If you've determined that it helps, consider using a built-in [`PureComponent`](/docs/react-api.html#reactpurecomponent) instead of writing `shouldComponentUpdate()` by hand if a shallow prop and state comparison is sufficient for your use case.**
244-
245282
`shouldComponentUpdate()` is invoked before rendering when new props or state are being received. Defaults to `true`. This method is not called for the initial render or when `forceUpdate()` is used.
246283

247-
Returning `false` does not prevent child components from re-rendering when *their* state changes.
248-
249-
Currently, if `shouldComponentUpdate()` returns `false`, then [`UNSAFE_componentWillUpdate()`](#unsafe_componentwillupdate), [`render()`](#render), and [`componentDidUpdate()`](#componentdidupdate) will not be invoked. Note that in the future React may treat `shouldComponentUpdate()` as a hint rather than a strict directive, and returning `false` may still result in a re-rendering of the component.
284+
**This method only exists as a performance optimization. Do not rely on it to "prevent" a rendering, as it typically leads to bugs.**
250285

251-
If you determine a specific component is slow after profiling, you may change it to inherit from [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) which implements `shouldComponentUpdate()` with a shallow prop and state comparison. If you are confident you want to write it by hand, you may compare `this.props` with `nextProps` and `this.state` with `nextState` and return `false` to tell React the update can be skipped.
286+
If you've [determined that adding this method is beneficial](/docs/optimizing-performance.html), **consider using the built-in [`PureComponent`](/docs/react-api.html#reactpurecomponent) instead of writing `shouldComponentUpdate()` by hand.** It performs a shallow comparison of props and state, and reduces the chance that you'll forget to update a component when it needs to.
252287

253288
We do not recommend doing deep equality checks or using `JSON.stringify()` in `shouldComponentUpdate()`. It is very inefficient and will harm performance.
254289

290+
If you are confident you want to write it by hand, you may compare `this.props` with `nextProps` and `this.state` with `nextState` and return `false` to tell React the update can be skipped. Note that returning `false` does not prevent child components from re-rendering when *their* state changes.
291+
292+
Currently, if `shouldComponentUpdate()` returns `false`, then [`UNSAFE_componentWillUpdate()`](#unsafe_componentwillupdate), [`render()`](#render), and [`componentDidUpdate()`](#componentdidupdate) will not be invoked. In the future React may treat `shouldComponentUpdate()` as a hint rather than a strict directive, and returning `false` may still result in a re-rendering of the component.
293+
255294
* * *
256295

257296
### `static getDerivedStateFromProps()`
@@ -272,7 +311,7 @@ This method exists for **very rare use cases** where the state depends on change
272311

273312
* If you want to **"mirror" a prop in the state**, consider either making a component [fully controlled](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) or [fully uncontrolled](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) instead. Both of these solutions are simpler and lead to fewer bugs.
274313

275-
You can find more guidance for whether to use `getDerivedStateFromProps()` in [this paragraph](/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state).
314+
You can find more guidance for whether to use `getDerivedStateFromProps()` in [this paragraph](/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state). If you decide to use it after all, note that it doesn't have access to the component instance (because it's a static method). If it needs some helper functions, you can extract them outside the component class, and keep them pure too. If it seems like it needs access to `this.setState()`, it probably means you either forget it needs to *return* the state, or you're keeping something in the state that can be calculated in the `render()` method instead.
276315

277316
Note that this method is fired on *every* render, regardless of the cause. This is in contrast to `UNSAFE_componentWillReceiveProps`, which only fires when the parent causes a re-render and not as a result of a local `setState`.
278317

@@ -385,9 +424,11 @@ Typically, this method can be replaced by `componentDidUpdate()`. If you were re
385424
386425
* * *
387426

388-
## Methods You Can Call
427+
## Other APIs
428+
429+
Unlike the lifecycle methods above (which React calls for you), the methods below are the methods *you* can call from your components.
389430

390-
Unlike the lifecycle methods above (which React calls for you), the methods below are the methods *you* can call from your components. There are just two of them: `setState()` and `forceUpdate()`.
431+
There are just two of them: `setState()` and `forceUpdate()`.
391432

392433
### `setState()`
393434

0 commit comments

Comments
 (0)