Skip to content

Commit 454f7e1

Browse files
author
Jack Pope
committed
Contain changes within canary block
1 parent f687157 commit 454f7e1

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

src/content/learn/manipulating-the-dom-with-refs.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ This is because **Hooks must only be called at the top-level of your component.*
211211

212212
One possible way around this is to get a single ref to their parent element, and then use DOM manipulation methods like [`querySelectorAll`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) to "find" the individual child nodes from it. However, this is brittle and can break if your DOM structure changes.
213213

214-
Another solution is to **pass a function to the `ref` attribute.** This is called a [`ref` callback.](/reference/react-dom/components/common#ref-callback) React will call your ref callback with the DOM node when it's time to set the ref, and call your cleanup function when it's time to clear it. This lets you maintain your own array or a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), and access any ref by its index or some kind of ID.
214+
Another solution is to **pass a function to the `ref` attribute.** This is called a [`ref` callback.](/reference/react-dom/components/common#ref-callback) React will call your ref callback with the DOM node when it's time to set the ref, and with `null` when it's time to clear it. This lets you maintain your own array or a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), and access any ref by its index or some kind of ID.
215215

216216
This example shows how you can use this approach to scroll to an arbitrary node in a long list:
217217

@@ -256,8 +256,8 @@ export default function CatFriends() {
256256
<button onClick={addCat}>Add Cat</button>
257257
<button onClick={removeCat}>Remove Cat</button>
258258
<button onClick={() => scrollToCat(catList[0])}>Tom</button>
259-
<button onClick={() => scrollToCat(catList[5])}>Maru</button>
260-
<button onClick={() => scrollToCat(catList[9])}>Jellylorum</button>
259+
<button onClick={() => scrollToCat(catList[Math.floor((catList.length - 1) / 2)])}>Maru</button>
260+
<button onClick={() => scrollToCat(catList[catList.length - 1])}>Jellylorum</button>
261261
</nav>
262262
<div>
263263
<ul>
@@ -266,11 +266,11 @@ export default function CatFriends() {
266266
key={cat}
267267
ref={(node) => {
268268
const map = getMap();
269+
if (node) {
269270
map.set(cat, node);
270-
271-
return () => {
271+
} else {
272272
map.delete(cat);
273-
};
273+
}
274274
}}
275275
>
276276
<img src={cat} />

src/content/reference/react-dom/components/common.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,21 +251,38 @@ Instead of a ref object (like the one returned by [`useRef`](/reference/react/us
251251

252252
[See an example of using the `ref` callback.](/learn/manipulating-the-dom-with-refs#how-to-manage-a-list-of-refs-using-a-ref-callback)
253253

254-
When the `<div>` DOM node is added to the screen, React will call your `ref` callback with the DOM `node` as the argument. If a cleanup function is returned, React will call it when that `<div>` DOM node is removed. Without a cleanup function, React will call your `ref` callback again with `null` when the node is removed.
254+
When the `<div>` DOM node is added to the screen, React will call your `ref` callback with the DOM `node` as the argument. When that `<div>` DOM node is removed, React will call your `ref` callback with `null`.
255255

256-
React will also call your `ref` callback whenever you pass a *different* `ref` callback. In the above example, `(node) => { ... }` is a different function on every render. When your component re-renders, React will call the *previous* callback's cleanup function if provided. If not cleanup function is defined, the `ref` callback will be called with `null` as the argument. The *next* function will be called with the DOM node.
256+
React will also call your `ref` callback whenever you pass a *different* `ref` callback. In the above example, `(node) => { ... }` is a different function on every render. When your component re-renders, the *previous* function will be called with `null` as the argument, and the *next* function will be called with the DOM node.
257257

258258
#### Parameters {/*ref-callback-parameters*/}
259259

260-
* `node`: A DOM node or `null`. React will pass you the DOM node when the ref gets attached, and `null` when the `ref` gets detached if no cleanup function is returned. Unless you pass the same function reference for the `ref` callback on every render, the callback will get temporarily detached and re-attached during every re-render of the component.
260+
* `node`: A DOM node or `null`. React will pass you the DOM node when the ref gets attached, and `null` when the `ref` gets detached. Unless you pass the same function reference for the `ref` callback on every render, the callback will get temporarily detached and re-attached during every re-render of the component.
261+
262+
<Canary>
261263

262264
#### Returns {/*returns*/}
263265

264-
* <CanaryBadge title="This feature is only available in the Canary channel" /> **optional** `cleanup function`: When the `ref` is detached, React will call the cleanup function. If a function is not returned by the `ref` callback, React will call the callback again with `null` as the argument when the `ref` gets detached.
266+
* **optional** `cleanup function`: When the `ref` is detached, React will call the cleanup function. If a function is not returned by the `ref` callback, React will call the callback again with `null` as the argument when the `ref` gets detached.
267+
268+
```js
269+
270+
<div ref={(node) => {
271+
console.log(node);
272+
273+
return () => {
274+
console.log('Clean up', node)
275+
}
276+
}}>
277+
278+
```
265279

266280
#### Caveats {/*caveats*/}
267281

268-
* <CanaryBadge title="This feature is only available in the Canary channel" /> When Strict Mode is on, React will **run one extra development-only setup+cleanup cycle** before the first real setup. This is a stress-test that ensures that your cleanup logic "mirrors" your setup logic and that it stops or undoes whatever the setup is doing. If this causes a problem, implement the cleanup function.
282+
* When Strict Mode is on, React will **run one extra development-only setup+cleanup cycle** before the first real setup. This is a stress-test that ensures that your cleanup logic "mirrors" your setup logic and that it stops or undoes whatever the setup is doing. If this causes a problem, implement the cleanup function.
283+
* When you pass a *different* `ref` callback, React will call the *previous* callback's cleanup function if provided. If not cleanup function is defined, the `ref` callback will be called with `null` as the argument. The *next* function will be called with the DOM node.
284+
285+
</Canary>
269286

270287
---
271288

0 commit comments

Comments
 (0)