Skip to content

Commit 649211b

Browse files
Address Dan's feedback
1 parent b89d0b6 commit 649211b

File tree

2 files changed

+80
-6
lines changed

2 files changed

+80
-6
lines changed

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

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,15 +347,32 @@ Read more about [how this helps find bugs](/reference/react/StrictMode#fixing-bu
347347
Refs are an escape hatch that should be used sparingly. Manually manipulating _another_ component's DOM nodes makes your code even more fragile.
348348
</Pitfall>
349349

350-
When you put a ref on a built-in component that outputs a browser element like `<input />`, React will set that ref's `current` property to the corresponding DOM node (such as the actual `<input />` in the browser).
350+
You can pass refs from parent component to child components [just like any other prop](/learn/passing-props-to-a-component).
351+
352+
```js {3-4,9}
353+
import { useRef } from 'react';
354+
355+
function MyInput({ref}) {
356+
return <input ref={ref} />;
357+
}
358+
359+
function MyForm() {
360+
const inputRef = useRef(null);
361+
return <><MyInput ref={inputRef} /></>
362+
}
363+
```
364+
365+
In the above example, a ref is created in the parent component, `MyForm`, and is passed to the child component, `MyInput`. `MyInput` then passes the ref to `<input>`. Because `<input>` is a [built-in component](/reference/react-dom/components/common) React sets the `.current` property of the ref to the `<input>` DOM element.
366+
367+
The `inputRef` created in `MyForm` now points to the `<input>` DOM element returned by `MyInput`. A click handler created in `MyForm` can access `inputRef` and call `focus()` to set the focus on `<input>`.
351368

352369
<Sandpack>
353370

354371
```js
355372
import { useRef } from 'react';
356373

357-
function MyInput(props) {
358-
return <input {...props} />;
374+
function MyInput({ref}) {
375+
return <input ref={ref} />;
359376
}
360377

361378
export default function MyForm() {
@@ -530,7 +547,7 @@ export default function TodoList() {
530547
const newTodo = { id: nextId++, text: text };
531548
flushSync(() => {
532549
setText('');
533-
setTodos([ ...todos, newTodo]);
550+
setTodos([ ...todos, newTodo]);
534551
});
535552
listRef.current.lastChild.scrollIntoView({
536553
behavior: 'smooth',

src/content/reference/react/useRef.md

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,8 @@ Sometimes, you may want to let the parent component manipulate the DOM inside of
455455
```js
456456
import { useRef } from 'react';
457457

458-
const MyInput = (props, ref) => {
459-
return <input {...props} ref={ref} />;
458+
const MyInput = ({ref}) => {
459+
return <input ref={ref} />;
460460
};
461461

462462
export default function Form() {
@@ -535,3 +535,60 @@ function Video() {
535535
Here, the `playerRef` itself is nullable. However, you should be able to convince your type checker that there is no case in which `getPlayer()` returns `null`. Then use `getPlayer()` in your event handlers.
536536
537537
</DeepDive>
538+
539+
---
540+
541+
## Troubleshooting {/*troubleshooting*/}
542+
543+
### I can't get a ref to a custom component {/*i-cant-get-a-ref-to-a-custom-component*/}
544+
545+
If you try to pass a `ref` to your own component like this:
546+
547+
```js
548+
const inputRef = useRef(null);
549+
550+
return <MyInput ref={inputRef} />;
551+
```
552+
553+
You might get an error in the console:
554+
555+
<ConsoleBlock level="error">
556+
557+
TypeError: Cannot read properties of null
558+
559+
</ConsoleBlock>
560+
561+
By default, your own components don't expose refs to the DOM nodes inside them.
562+
563+
To fix this, find the component that you want to get a ref to:
564+
565+
```js
566+
export default function MyInput({ value, onChange }) {
567+
return (
568+
<input
569+
value={value}
570+
onChange={onChange}
571+
/>
572+
);
573+
}
574+
```
575+
576+
And then add `ref` to the list of props your component accepts and pass `ref` as a prop to the relevent child [built-in component](/reference/react-dom/components/common) like this:
577+
578+
```js {1,6}
579+
const MyInput = ({ value, onChange, ref}) => {
580+
return (
581+
<input
582+
value={value}
583+
onChange={onChange}
584+
ref={ref}
585+
/>
586+
);
587+
};
588+
589+
export default MyInput;
590+
```
591+
592+
Then the parent component can get a ref to it.
593+
594+
Read more about [accessing another component's DOM nodes.](/learn/manipulating-the-dom-with-refs#accessing-another-components-dom-nodes)

0 commit comments

Comments
 (0)