Skip to content

Commit b4f2728

Browse files
Merge branch 'master' of https://github.com/reactjs/reactjs.org into sync-b1bc193d
2 parents 036e1c1 + b1bc193 commit b4f2728

File tree

3 files changed

+98
-7
lines changed

3 files changed

+98
-7
lines changed

content/community/conferences.md

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ July 15-21, 2019. New York City, USA
5757

5858
[Website](https://reactweek.nyc) - [Twitter](https://twitter.com/ReactWeek)
5959

60+
### React Rally 2019
61+
August 22-23, 2019. Salt Lake City, USA.
62+
63+
[Website](https://www.reactrally.com/) - [Twitter](https://twitter.com/ReactRally) - [Instagram](https://www.instagram.com/reactrally/)
64+
6065
### ComponentsConf 2019 {#componentsconf-2019}
6166
September 6, 2019 in Melbourne, Australia
6267
[Website](https://www.componentsconf.com.au/) - [Twitter](https://twitter.com/componentsconf)

content/docs/hooks-faq.md

+57-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ This page answers some of the frequently asked questions about [Hooks](/docs/hoo
4141
* [How do I implement getDerivedStateFromProps?](#how-do-i-implement-getderivedstatefromprops)
4242
* [Is there something like forceUpdate?](#is-there-something-like-forceupdate)
4343
* [Can I make a ref to a function component?](#can-i-make-a-ref-to-a-function-component)
44+
* [How can I measure a DOM node?](#how-can-i-measure-a-dom-node)
4445
* [What does const [thing, setThing] = useState() mean?](#what-does-const-thing-setthing--usestate-mean)
4546
* **[Performance Optimizations](#performance-optimizations)**
4647
* [Can I skip an effect on updates?](#can-i-skip-an-effect-on-updates)
@@ -451,6 +452,60 @@ Try to avoid this pattern if possible.
451452

452453
While you shouldn't need this often, you may expose some imperative methods to a parent component with the [`useImperativeHandle`](/docs/hooks-reference.html#useimperativehandle) Hook.
453454

455+
### How can I measure a DOM node? {#how-can-i-measure-a-dom-node}
456+
457+
In order to measure the position or size of a DOM node, you can use a [callback ref](/docs/refs-and-the-dom.html#callback-refs). React will call that callback whenever the ref gets attached to a different node. Here is a [small demo](https://codesandbox.io/s/l7m0v5x4v9):
458+
459+
```js{4-8,12}
460+
function MeasureExample() {
461+
const [height, setHeight] = useState(0);
462+
463+
const measuredRef = useCallback(node => {
464+
if (node !== null) {
465+
setHeight(node.getBoundingClientRect().height);
466+
}
467+
}, []);
468+
469+
return (
470+
<>
471+
<h1 ref={measuredRef}>Hello, world</h1>
472+
<h2>The above header is {Math.round(height)}px tall</h2>
473+
</>
474+
);
475+
}
476+
```
477+
478+
We didn't choose `useRef` in this example because an object ref doesn't notify us about *changes* to the current ref value. Using a callback ref ensures that [even if a child component displays the measured node later](https://codesandbox.io/s/818zzk8m78) (e.g. in response to a click), we still get notified about it in the parent component and can update the measurements.
479+
480+
Note that we pass `[]` as a dependency array to `useCallback`. This ensures that our ref callback doesn't change between the re-renders, and so React won't call it unnecessarily.
481+
482+
If you want, you can [extract this logic](https://codesandbox.io/s/m5o42082xy) into a reusable Hook:
483+
484+
```js{2}
485+
function MeasureExample() {
486+
const [rect, ref] = useClientRect();
487+
return (
488+
<>
489+
<h1 ref={ref}>Hello, world</h1>
490+
{rect !== null &&
491+
<h2>The above header is {Math.round(rect.height)}px tall</h2>
492+
}
493+
</>
494+
);
495+
}
496+
497+
function useClientRect() {
498+
const [rect, setRect] = useState(null);
499+
const ref = useCallback(node => {
500+
if (node !== null) {
501+
setRect(node.getBoundingClientRect());
502+
}
503+
}, []);
504+
return [rect, ref];
505+
}
506+
```
507+
508+
454509
### What does `const [thing, setThing] = useState()` mean? {#what-does-const-thing-setthing--usestate-mean}
455510

456511
If you're not familiar with this syntax, check out the [explanation](/docs/hooks-state.html#tip-what-do-square-brackets-mean) in the State Hook documentation.
@@ -853,7 +908,7 @@ function Form() {
853908
const [text, updateText] = useState('');
854909
const textRef = useRef();
855910
856-
useLayoutEffect(() => {
911+
useEffect(() => {
857912
textRef.current = text; // Write it to the ref
858913
});
859914
@@ -894,7 +949,7 @@ function useEventCallback(fn, dependencies) {
894949
throw new Error('Cannot call an event handler while rendering.');
895950
});
896951
897-
useLayoutEffect(() => {
952+
useEffect(() => {
898953
ref.current = fn;
899954
}, [fn, ...dependencies]);
900955

content/docs/hooks-reference.md

+36-5
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ const [state, setState] = useState(() => {
9797

9898
If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the [`Object.is` comparison algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).)
9999

100+
Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`.
101+
100102
### `useEffect` {#useeffect}
101103

102104
```js
@@ -173,12 +175,26 @@ The array of dependencies is not passed as arguments to the effect function. Con
173175
### `useContext` {#usecontext}
174176

175177
```js
176-
const context = useContext(Context);
178+
const value = useContext(MyContext);
177179
```
178180

179-
Accepts a context object (the value returned from `React.createContext`) and returns the current context value, as given by the nearest context provider for the given context.
181+
Accepts a context object (the value returned from `React.createContext`) and returns the current context value for that context. The current context value is determined by the `value` prop of the nearest `<MyContext.Provider>` above the calling component in the tree.
182+
183+
When the nearest `<MyContext.Provider>` above the component updates, this Hook will trigger a rerender with the latest context `value` passed to that `MyContext` provider.
184+
185+
Don't forget that the argument to `useContext` must be the *context object itself*:
186+
187+
* **Correct:** `useContext(MyContext)`
188+
* **Incorrect:** `useContext(MyContext.Consumer)`
189+
* **Incorrect:** `useContext(MyContext.Provider)`
180190

181-
When the provider updates, this Hook will trigger a rerender with the latest context value.
191+
A component calling `useContext` will always re-render when the context value changes. If re-rendering the component is expensive, you can [optimize it by using memoization](https://github.com/facebook/react/issues/15156#issuecomment-474590693).
192+
193+
>Tip
194+
>
195+
>If you're familiar with the context API before Hooks, `useContext(MyContext)` is equivalent to `static contextType = MyContext` in a class, or to `<MyContext.Consumer>`.
196+
>
197+
>`useContext(MyContext)` only lets you *read* the context and subscribe to its changes. You still need a `<MyContext.Provider>` above in the tree to *provide* the value for this context.
182198
183199
## Additional Hooks {#additional-hooks}
184200

@@ -285,6 +301,8 @@ function Counter({initialCount}) {
285301

286302
If you return the same value from a Reducer Hook as the current state, React will bail out without rendering the children or firing effects. (React uses the [`Object.is` comparison algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).)
287303

304+
Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`.
305+
288306
### `useCallback` {#usecallback}
289307

290308
```js
@@ -356,7 +374,16 @@ function TextInputWithFocusButton() {
356374
}
357375
```
358376

359-
Note that `useRef()` is useful for more than the `ref` attribute. It's [handy for keeping any mutable value around](/docs/hooks-faq.html#is-there-something-like-instance-variables) similar to how you'd use instance fields in classes.
377+
Essentially, `useRef` is like a "box" that can hold a mutable value in its `.current` property.
378+
379+
You might be familiar with refs primarily as a way to [access the DOM](/docs/refs-and-the-dom.html). If you pass a ref object to React with `<div ref={myRef} />`, React will set its `.current` property to the corresponding DOM node whenever that node changes.
380+
381+
However, `useRef()` is useful for more than the `ref` attribute. It's [handy for keeping any mutable value around](/docs/hooks-faq.html#is-there-something-like-instance-variables) similar to how you'd use instance fields in classes.
382+
383+
This works because `useRef()` creates a plain JavaScript object. The only difference between `useRef()` and creating a `{current: ...}` object yourself is that `useRef` will give you the same ref object on every render.
384+
385+
Keep in mind that `useRef` *doesn't* notify you when its content changes. Mutating the `.current` property doesn't cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a [callback ref](/docs/hooks-faq.html#how-can-i-measure-a-dom-node) instead.
386+
360387

361388
### `useImperativeHandle` {#useimperativehandle}
362389

@@ -389,7 +416,11 @@ Prefer the standard `useEffect` when possible to avoid blocking visual updates.
389416

390417
> Tip
391418
>
392-
> If you're migrating code from a class component, `useLayoutEffect` fires in the same phase as `componentDidMount` and `componentDidUpdate`, so if you're unsure of which effect Hook to use, it's probably the least risky.
419+
> If you're migrating code from a class component, note `useLayoutEffect` fires in the same phase as `componentDidMount` and `componentDidUpdate`. However, **we recommend starting with `useEffect` first** and only trying `useLayoutEffect` if that causes a problem.
420+
>
421+
>If you use server rendering, keep in mind that *neither* `useLayoutEffect` nor `useEffect` can run until the JavaScript is downloaded. This is why React warns when a server-rendered component contains `useLayoutEffect`. To fix this, either move that logic to `useEffect` (if it isn't necessary for the first render), or delay showing that component until after the client renders (if the HTML looks broken until `useLayoutEffect` runs).
422+
>
423+
>To exclude a component that needs layout effects from the server-rendered HTML, render it conditionally with `showChild && <Child />` and defer showing it with `useEffect(() => { setShowChild(true); }, [])`. This way, the UI doesn't appear broken before hydration.
393424
394425
### `useDebugValue` {#usedebugvalue}
395426

0 commit comments

Comments
 (0)