Skip to content

Commit c37fdd3

Browse files
SebassNoobgaearon
andauthored
Remove forwardref from useImperativeHandle docs (#7360)
* fix: remove forwardref from useImperativeHandle docs * Make changes more focused * Update useImperativeHandle.md --------- Co-authored-by: dan <[email protected]>
1 parent 9985199 commit c37fdd3

File tree

1 file changed

+36
-32
lines changed

1 file changed

+36
-32
lines changed

src/content/reference/react/useImperativeHandle.md

+36-32
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ useImperativeHandle(ref, createHandle, dependencies?)
2323
Call `useImperativeHandle` at the top level of your component to customize the ref handle it exposes:
2424
2525
```js
26-
import { forwardRef, useImperativeHandle } from 'react';
26+
import { useImperativeHandle } from 'react';
2727

28-
const MyInput = forwardRef(function MyInput(props, ref) {
28+
function MyInput({ ref }) {
2929
useImperativeHandle(ref, () => {
3030
return {
3131
// ... your methods ...
@@ -38,12 +38,18 @@ const MyInput = forwardRef(function MyInput(props, ref) {
3838
3939
#### Parameters {/*parameters*/}
4040
41-
* `ref`: The `ref` you received as the second argument from the [`forwardRef` render function.](/reference/react/forwardRef#render-function)
41+
* `ref`: The `ref` you received as a prop to the `MyInput` component.
4242
4343
* `createHandle`: A function that takes no arguments and returns the ref handle you want to expose. That ref handle can have any type. Usually, you will return an object with the methods you want to expose.
4444
4545
* **optional** `dependencies`: The list of all reactive values referenced inside of the `createHandle` code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is [configured for React](/learn/editor-setup#linting), it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like `[dep1, dep2, dep3]`. React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. If a re-render resulted in a change to some dependency, or if you omitted this argument, your `createHandle` function will re-execute, and the newly created handle will be assigned to the ref.
4646
47+
<Note>
48+
49+
Starting with React 19, [`ref` is available a prop.](/blog/2024/12/05/react-19#ref-as-a-prop) In React 18 and earlier, it was necessary to get the `ref` from [`forwardRef`.](/reference/react/forwardRef)
50+
51+
</Note>
52+
4753
#### Returns {/*returns*/}
4854
4955
`useImperativeHandle` returns `undefined`.
@@ -54,40 +60,38 @@ const MyInput = forwardRef(function MyInput(props, ref) {
5460
5561
### Exposing a custom ref handle to the parent component {/*exposing-a-custom-ref-handle-to-the-parent-component*/}
5662
57-
By default, components don't expose their DOM nodes to parent components. For example, if you want the parent component of `MyInput` to [have access](/learn/manipulating-the-dom-with-refs) to the `<input>` DOM node, you have to opt in with [`forwardRef`:](/reference/react/forwardRef)
58-
59-
```js {4}
60-
import { forwardRef } from 'react';
63+
To expose a DOM node to the parent element, pass in the `ref` prop to the node.
6164
62-
const MyInput = forwardRef(function MyInput(props, ref) {
63-
return <input {...props} ref={ref} />;
64-
});
65+
```js {2}
66+
function MyInput({ ref }) {
67+
return <input ref={ref} />;
68+
};
6569
```
6670
67-
With the code above, [a ref to `MyInput` will receive the `<input>` DOM node.](/reference/react/forwardRef#exposing-a-dom-node-to-the-parent-component) However, you can expose a custom value instead. To customize the exposed handle, call `useImperativeHandle` at the top level of your component:
71+
With the code above, [a ref to `MyInput` will receive the `<input>` DOM node.](/learn/manipulating-the-dom-with-refs) However, you can expose a custom value instead. To customize the exposed handle, call `useImperativeHandle` at the top level of your component:
6872
6973
```js {4-8}
70-
import { forwardRef, useImperativeHandle } from 'react';
74+
import { useImperativeHandle } from 'react';
7175

72-
const MyInput = forwardRef(function MyInput(props, ref) {
76+
function MyInput({ ref }) {
7377
useImperativeHandle(ref, () => {
7478
return {
7579
// ... your methods ...
7680
};
7781
}, []);
7882

79-
return <input {...props} />;
80-
});
83+
return <input />;
84+
};
8185
```
8286
83-
Note that in the code above, the `ref` is no longer forwarded to the `<input>`.
87+
Note that in the code above, the `ref` is no longer passed to the `<input>`.
8488
8589
For example, suppose you don't want to expose the entire `<input>` DOM node, but you want to expose two of its methods: `focus` and `scrollIntoView`. To do this, keep the real browser DOM in a separate ref. Then use `useImperativeHandle` to expose a handle with only the methods that you want the parent component to call:
8690
8791
```js {7-14}
88-
import { forwardRef, useRef, useImperativeHandle } from 'react';
92+
import { useRef, useImperativeHandle } from 'react';
8993

90-
const MyInput = forwardRef(function MyInput(props, ref) {
94+
function MyInput({ ref }) {
9195
const inputRef = useRef(null);
9296

9397
useImperativeHandle(ref, () => {
@@ -101,8 +105,8 @@ const MyInput = forwardRef(function MyInput(props, ref) {
101105
};
102106
}, []);
103107

104-
return <input {...props} ref={inputRef} />;
105-
});
108+
return <input ref={inputRef} />;
109+
};
106110
```
107111
108112
Now, if the parent component gets a ref to `MyInput`, it will be able to call the `focus` and `scrollIntoView` methods on it. However, it will not have full access to the underlying `<input>` DOM node.
@@ -134,9 +138,9 @@ export default function Form() {
134138
```
135139
136140
```js src/MyInput.js
137-
import { forwardRef, useRef, useImperativeHandle } from 'react';
141+
import { useRef, useImperativeHandle } from 'react';
138142

139-
const MyInput = forwardRef(function MyInput(props, ref) {
143+
function MyInput({ ref, ...props }) {
140144
const inputRef = useRef(null);
141145

142146
useImperativeHandle(ref, () => {
@@ -151,7 +155,7 @@ const MyInput = forwardRef(function MyInput(props, ref) {
151155
}, []);
152156

153157
return <input {...props} ref={inputRef} />;
154-
});
158+
};
155159

156160
export default MyInput;
157161
```
@@ -195,11 +199,11 @@ export default function Page() {
195199
```
196200
197201
```js src/Post.js
198-
import { forwardRef, useRef, useImperativeHandle } from 'react';
202+
import { useRef, useImperativeHandle } from 'react';
199203
import CommentList from './CommentList.js';
200204
import AddComment from './AddComment.js';
201205

202-
const Post = forwardRef((props, ref) => {
206+
function Post({ ref }) {
203207
const commentsRef = useRef(null);
204208
const addCommentRef = useRef(null);
205209

@@ -221,16 +225,16 @@ const Post = forwardRef((props, ref) => {
221225
<AddComment ref={addCommentRef} />
222226
</>
223227
);
224-
});
228+
};
225229

226230
export default Post;
227231
```
228232
229233
230234
```js src/CommentList.js
231-
import { forwardRef, useRef, useImperativeHandle } from 'react';
235+
import { useRef, useImperativeHandle } from 'react';
232236

233-
const CommentList = forwardRef(function CommentList(props, ref) {
237+
function CommentList({ ref }) {
234238
const divRef = useRef(null);
235239

236240
useImperativeHandle(ref, () => {
@@ -252,17 +256,17 @@ const CommentList = forwardRef(function CommentList(props, ref) {
252256
{comments}
253257
</div>
254258
);
255-
});
259+
}
256260

257261
export default CommentList;
258262
```
259263
260264
```js src/AddComment.js
261-
import { forwardRef, useRef, useImperativeHandle } from 'react';
265+
import { useRef, useImperativeHandle } from 'react';
262266

263-
const AddComment = forwardRef(function AddComment(props, ref) {
267+
function AddComment({ ref }) {
264268
return <input placeholder="Add comment..." ref={ref} />;
265-
});
269+
}
266270

267271
export default AddComment;
268272
```

0 commit comments

Comments
 (0)