Skip to content

Commit 1416468

Browse files
committed
fix: remove forwardref from useImperativeHandle docs
1 parent 3b02f82 commit 1416468

File tree

1 file changed

+33
-28
lines changed

1 file changed

+33
-28
lines changed

src/content/reference/react/useImperativeHandle.md

Lines changed: 33 additions & 28 deletions
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, ...props }) {
2929
useImperativeHandle(ref, () => {
3030
return {
3131
// ... your methods ...
@@ -38,12 +38,19 @@ 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+
In versions prior to React 19, components by default don't expose their DOM nodes to parent components. This was done by opting in with [`forwardRef`](/reference/react/forwardRef) for the parent component to [have access](/learn/manipulating-the-dom-with-refs) to the child's DOM node.
49+
50+
`forwardRef` is now depreciated. Read the blog on [`ref` as a prop](/blog/2024/12/05/react-19#ref-as-a-prop) to learn more.
51+
52+
</Note>
53+
4754
#### Returns {/*returns*/}
4855
4956
`useImperativeHandle` returns `undefined`.
@@ -54,40 +61,38 @@ const MyInput = forwardRef(function MyInput(props, ref) {
5461
5562
### Exposing a custom ref handle to the parent component {/*exposing-a-custom-ref-handle-to-the-parent-component*/}
5663
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)
64+
To expose a DOM node to the parent element, pass in the `ref` prop to the node.
5865
59-
```js {4}
60-
import { forwardRef } from 'react';
61-
62-
const MyInput = forwardRef(function MyInput(props, ref) {
66+
```js {2}
67+
function MyInput({ ref, ...props }) {
6368
return <input {...props} ref={ref} />;
64-
});
69+
};
6570
```
6671
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:
72+
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:
6873
6974
```js {4-8}
70-
import { forwardRef, useImperativeHandle } from 'react';
75+
import { useImperativeHandle } from 'react';
7176

72-
const MyInput = forwardRef(function MyInput(props, ref) {
77+
function MyInput({ ref, ...props }) {
7378
useImperativeHandle(ref, () => {
7479
return {
7580
// ... your methods ...
7681
};
7782
}, []);
7883

7984
return <input {...props} />;
80-
});
85+
};
8186
```
8287
8388
Note that in the code above, the `ref` is no longer forwarded to the `<input>`.
8489
8590
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:
8691
8792
```js {7-14}
88-
import { forwardRef, useRef, useImperativeHandle } from 'react';
93+
import { useRef, useImperativeHandle } from 'react';
8994

90-
const MyInput = forwardRef(function MyInput(props, ref) {
95+
function MyInput({ ref, ...props }) {
9196
const inputRef = useRef(null);
9297

9398
useImperativeHandle(ref, () => {
@@ -102,7 +107,7 @@ const MyInput = forwardRef(function MyInput(props, ref) {
102107
}, []);
103108

104109
return <input {...props} ref={inputRef} />;
105-
});
110+
};
106111
```
107112
108113
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 +139,9 @@ export default function Form() {
134139
```
135140
136141
```js src/MyInput.js
137-
import { forwardRef, useRef, useImperativeHandle } from 'react';
142+
import { useRef, useImperativeHandle } from 'react';
138143

139-
const MyInput = forwardRef(function MyInput(props, ref) {
144+
function MyInput({ ref, ...props }) {
140145
const inputRef = useRef(null);
141146

142147
useImperativeHandle(ref, () => {
@@ -151,7 +156,7 @@ const MyInput = forwardRef(function MyInput(props, ref) {
151156
}, []);
152157

153158
return <input {...props} ref={inputRef} />;
154-
});
159+
};
155160

156161
export default MyInput;
157162
```
@@ -195,11 +200,11 @@ export default function Page() {
195200
```
196201
197202
```js src/Post.js
198-
import { forwardRef, useRef, useImperativeHandle } from 'react';
203+
import { useRef, useImperativeHandle } from 'react';
199204
import CommentList from './CommentList.js';
200205
import AddComment from './AddComment.js';
201206

202-
const Post = forwardRef((props, ref) => {
207+
function Post({ ref, ...props }) {
203208
const commentsRef = useRef(null);
204209
const addCommentRef = useRef(null);
205210

@@ -221,16 +226,16 @@ const Post = forwardRef((props, ref) => {
221226
<AddComment ref={addCommentRef} />
222227
</>
223228
);
224-
});
229+
};
225230

226231
export default Post;
227232
```
228233
229234
230235
```js src/CommentList.js
231-
import { forwardRef, useRef, useImperativeHandle } from 'react';
236+
import { useRef, useImperativeHandle } from 'react';
232237

233-
const CommentList = forwardRef(function CommentList(props, ref) {
238+
function CommentList({ ref, ...props }) {
234239
const divRef = useRef(null);
235240

236241
useImperativeHandle(ref, () => {
@@ -252,17 +257,17 @@ const CommentList = forwardRef(function CommentList(props, ref) {
252257
{comments}
253258
</div>
254259
);
255-
});
260+
}
256261

257262
export default CommentList;
258263
```
259264
260265
```js src/AddComment.js
261-
import { forwardRef, useRef, useImperativeHandle } from 'react';
266+
import { useRef, useImperativeHandle } from 'react';
262267

263-
const AddComment = forwardRef(function AddComment(props, ref) {
268+
function AddComment({ ref, ...props }) {
264269
return <input placeholder="Add comment..." ref={ref} />;
265-
});
270+
}
266271

267272
export default AddComment;
268273
```

0 commit comments

Comments
 (0)