Skip to content

Commit 2859208

Browse files
authored
docs(hooks): improving useImperativeHandle example (#542)
* docs(hooks): improving useImperativeHandle example * Update hooks.md * chore(readme): running codegen * chore: formatting files
1 parent 9ec8261 commit 2859208

File tree

2 files changed

+78
-16
lines changed

2 files changed

+78
-16
lines changed

README.md

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -559,22 +559,53 @@ function Foo() {
559559

560560
#### useImperativeHandle
561561

562-
_We don't have much here, but this is from [a discussion in our issues](https://github.com/typescript-cheatsheets/react/issues/106). Please contribute if you have anything to add!_
562+
Based on this [Stackoverflow answer](https://stackoverflow.com/a/69292925/5415299):
563563

564564
```tsx
565-
type ListProps<ItemType> = {
566-
items: ItemType[];
567-
innerRef?: React.Ref<{ scrollToItem(item: ItemType): void }>;
565+
// Countdown.tsx
566+
567+
// Define the handle types which will be passed to the forwardRef
568+
export type CountdownHandle = {
569+
start: () => void;
568570
};
569571

570-
function List<ItemType>(props: ListProps<ItemType>) {
571-
useImperativeHandle(props.innerRef, () => ({
572-
scrollToItem() {},
572+
type CountdownProps = {};
573+
574+
const Countdown = forwardRef<CountdownHandle, CountdownProps>((props, ref) => {
575+
useImperativeHandle(ref, () => ({
576+
// start() has type inference here
577+
start() {
578+
alert("Start");
579+
},
573580
}));
574-
return null;
581+
582+
return <div>Countdown</div>;
583+
});
584+
```
585+
586+
```tsx
587+
// The component uses the Countdown component
588+
589+
import Countdown, { CountdownHandle } from "./Countdown.tsx";
590+
591+
function App() {
592+
const countdownEl = useRef<CountdownHandle>(null);
593+
594+
useEffect(() => {
595+
if (countdownEl.current) {
596+
// start() has type inference here as well
597+
countdownEl.current.start();
598+
}
599+
}, []);
600+
601+
return <Countdown ref={countdownEl} />;
575602
}
576603
```
577604

605+
##### See also:
606+
607+
- [Using ForwardRefRenderFunction](https://stackoverflow.com/a/62258685/5415299)
608+
578609
#### Custom Hooks
579610

580611
If you are returning an array in your Custom Hook, you will want to avoid type inference as TypeScript will infer a union type (when you actually want different types in each position of the array). Instead, use [TS 3.4 const assertions](https://devblogs.microsoft.com/typescript/announcing-typescript-3-4/#const-assertions):

docs/basic/getting-started/hooks.md

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -210,22 +210,53 @@ function Foo() {
210210

211211
## useImperativeHandle
212212

213-
_We don't have much here, but this is from [a discussion in our issues](https://github.com/typescript-cheatsheets/react/issues/106). Please contribute if you have anything to add!_
213+
Based on this [Stackoverflow answer](https://stackoverflow.com/a/69292925/5415299):
214214

215215
```tsx
216-
type ListProps<ItemType> = {
217-
items: ItemType[];
218-
innerRef?: React.Ref<{ scrollToItem(item: ItemType): void }>;
216+
// Countdown.tsx
217+
218+
// Define the handle types which will be passed to the forwardRef
219+
export type CountdownHandle = {
220+
start: () => void;
219221
};
220222

221-
function List<ItemType>(props: ListProps<ItemType>) {
222-
useImperativeHandle(props.innerRef, () => ({
223-
scrollToItem() {},
223+
type CountdownProps = {};
224+
225+
const Countdown = forwardRef<CountdownHandle, CountdownProps>((props, ref) => {
226+
useImperativeHandle(ref, () => ({
227+
// start() has type inference here
228+
start() {
229+
alert("Start");
230+
},
224231
}));
225-
return null;
232+
233+
return <div>Countdown</div>;
234+
});
235+
```
236+
237+
```tsx
238+
// The component uses the Countdown component
239+
240+
import Countdown, { CountdownHandle } from "./Countdown.tsx";
241+
242+
function App() {
243+
const countdownEl = useRef<CountdownHandle>(null);
244+
245+
useEffect(() => {
246+
if (countdownEl.current) {
247+
// start() has type inference here as well
248+
countdownEl.current.start();
249+
}
250+
}, []);
251+
252+
return <Countdown ref={countdownEl} />;
226253
}
227254
```
228255

256+
### See also:
257+
258+
- [Using ForwardRefRenderFunction](https://stackoverflow.com/a/62258685/5415299)
259+
229260
## Custom Hooks
230261

231262
If you are returning an array in your Custom Hook, you will want to avoid type inference as TypeScript will infer a union type (when you actually want different types in each position of the array). Instead, use [TS 3.4 const assertions](https://devblogs.microsoft.com/typescript/announcing-typescript-3-4/#const-assertions):

0 commit comments

Comments
 (0)