Skip to content

Commit 9499e6d

Browse files
Merge branch 'master' of https://github.com/reactjs/reactjs.org into sync-2cd4d0cf
2 parents 68b854d + 2cd4d0c commit 9499e6d

File tree

6 files changed

+323
-44
lines changed

6 files changed

+323
-44
lines changed

content/docs/hooks-custom.md

+12-12
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ import React, { useState, useEffect } from 'react';
1818
function FriendStatus(props) {
1919
const [isOnline, setIsOnline] = useState(null);
2020
21-
function handleStatusChange(status) {
22-
setIsOnline(status.isOnline);
23-
}
24-
2521
useEffect(() => {
22+
function handleStatusChange(status) {
23+
setIsOnline(status.isOnline);
24+
}
25+
2626
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
2727
return () => {
2828
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
@@ -44,11 +44,11 @@ import React, { useState, useEffect } from 'react';
4444
function FriendListItem(props) {
4545
const [isOnline, setIsOnline] = useState(null);
4646
47-
function handleStatusChange(status) {
48-
setIsOnline(status.isOnline);
49-
}
50-
5147
useEffect(() => {
48+
function handleStatusChange(status) {
49+
setIsOnline(status.isOnline);
50+
}
51+
5252
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
5353
return () => {
5454
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
@@ -79,11 +79,11 @@ import React, { useState, useEffect } from 'react';
7979
function useFriendStatus(friendID) {
8080
const [isOnline, setIsOnline] = useState(null);
8181
82-
function handleStatusChange(status) {
83-
setIsOnline(status.isOnline);
84-
}
85-
8682
useEffect(() => {
83+
function handleStatusChange(status) {
84+
setIsOnline(status.isOnline);
85+
}
86+
8787
ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
8888
return () => {
8989
ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);

content/docs/hooks-effect.md

+25-12
Original file line numberDiff line numberDiff line change
@@ -198,17 +198,17 @@ Let's see how we could write this component with Hooks.
198198
199199
You might be thinking that we'd need a separate effect to perform the cleanup. But code for adding and removing a subscription is so tightly related that `useEffect` is designed to keep it together. If your effect returns a function, React will run it when it is time to clean up:
200200
201-
```js{10-16}
201+
```js{6-16}
202202
import React, { useState, useEffect } from 'react';
203203

204204
function FriendStatus(props) {
205205
const [isOnline, setIsOnline] = useState(null);
206206

207-
function handleStatusChange(status) {
208-
setIsOnline(status.isOnline);
209-
}
210-
211207
useEffect(() => {
208+
function handleStatusChange(status) {
209+
setIsOnline(status.isOnline);
210+
}
211+
212212
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
213213
// Specify how to clean up after this effect:
214214
return function cleanup() {
@@ -237,6 +237,10 @@ We've learned that `useEffect` lets us express different kinds of side effects a
237237
238238
```js
239239
useEffect(() => {
240+
function handleStatusChange(status) {
241+
setIsOnline(status.isOnline);
242+
}
243+
240244
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
241245
return () => {
242246
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
@@ -316,15 +320,15 @@ function FriendStatusWithCounter(props) {
316320

317321
const [isOnline, setIsOnline] = useState(null);
318322
useEffect(() => {
323+
function handleStatusChange(status) {
324+
setIsOnline(status.isOnline);
325+
}
326+
319327
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
320328
return () => {
321329
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
322330
};
323331
});
324-
325-
function handleStatusChange(status) {
326-
setIsOnline(status.isOnline);
327-
}
328332
// ...
329333
}
330334
```
@@ -394,6 +398,7 @@ Now consider the version of this component that uses Hooks:
394398
function FriendStatus(props) {
395399
// ...
396400
useEffect(() => {
401+
// ...
397402
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
398403
return () => {
399404
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
@@ -449,8 +454,12 @@ When we render with `count` updated to `6`, React will compare the items in the
449454
450455
This also works for effects that have a cleanup phase:
451456
452-
```js{6}
457+
```js{10}
453458
useEffect(() => {
459+
function handleStatusChange(status) {
460+
setIsOnline(status.isOnline);
461+
}
462+
454463
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
455464
return () => {
456465
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
@@ -462,9 +471,13 @@ In the future, the second argument might get added automatically by a build-time
462471
463472
>Note
464473
>
465-
>If you use this optimization, make sure the array includes **any values from the outer scope that change over time and that are used by the effect**. Otherwise, your code will reference stale values from previous renders. We'll also discuss other optimization options in the [Hooks API reference](/docs/hooks-reference.html).
474+
>If you use this optimization, make sure the array includes **all values from the component scope (such as props and state) that change over time and that are used by the effect**. Otherwise, your code will reference stale values from previous renders. Learn more about [how to deal with functions](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) and [what to do when the array changes too often](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often).
475+
>
476+
>If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array (`[]`) as a second argument. This tells React that your effect doesn't depend on *any* values from props or state, so it never needs to re-run. This isn't handled as a special case -- it follows directly from how the inputs array always works.
477+
>
478+
>If you pass an empty array (`[]`), the props and state inside the effect will always have their initial values. While passing `[]` as the second argument is closer to the familiar `componentDidMount` and `componentWillUnmount` mental model, there are usually [better](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) [solutions](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often) to avoid re-running effects too often. Also, don't forget that React defers running `useEffect` until after the browser has painted, so doing extra work is less of a problem.
466479
>
467-
>If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array (`[]`) as a second argument. This tells React that your effect doesn't depend on *any* values from props or state, so it never needs to re-run. This isn't handled as a special case -- it follows directly from how the inputs array always works. While passing `[]` is closer to the familiar `componentDidMount` and `componentWillUnmount` mental model, we suggest not making it a habit because it often leads to bugs, [as discussed above](#explanation-why-effects-run-on-each-update). Don't forget that React defers running `useEffect` until after the browser has painted, so doing extra work is less of a problem.
480+
>We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix.
468481
469482
## Next Steps {#next-steps}
470483

0 commit comments

Comments
 (0)