Skip to content

Add docs for useCallback #586

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Nov 2, 2022
Merged
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,49 @@ setUser(newUser);

This temporarily "lies" to the TypeScript compiler that `{}` is of type `User`. You should follow up by setting the `user` state — if you don't, the rest of your code may rely on the fact that `user` is of type `User` and that may lead to runtime errors.

#### useCallback

You can type the `useCallback` just like any other function.

```ts
const memoizedCallback = useCallback(
(param1: string, param2: number) => {
console.log(param1, param2)
return { ok: true }
},
[...],
);
/**
* VSCode will show the following type:
* const memoizedCallback:
* (param1: string, param2: number) => { ok: boolean }
*/
```

Note that for React < 18, the function signature of `useCallback` typed arguments as `any[]` by default:

```ts
function useCallback<T extends (...args: any[]) => any>(
callback: T,
deps: DependencyList
): T;
```

In React >= 18, the function signature of `useCallback` changed to the following:

```ts
function useCallback<T extends Function>(callback: T, deps: DependencyList): T;
```

Therefore, the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17.

```ts
// @ts-expect-error Parameter 'e' implicitly has 'any' type.
useCallback((e) => {}, []);
// Explicit 'any' type.
useCallback((e: any) => {}, []);
```

#### useReducer

You can use [Discriminated Unions](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions) for reducer actions. Don't forget to define the return type of reducer, otherwise TypeScript will infer it.
Expand Down
43 changes: 43 additions & 0 deletions docs/basic/getting-started/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,49 @@ setUser(newUser);

This temporarily "lies" to the TypeScript compiler that `{}` is of type `User`. You should follow up by setting the `user` state — if you don't, the rest of your code may rely on the fact that `user` is of type `User` and that may lead to runtime errors.

## useCallback

You can type the `useCallback` just like any other function.

```ts
const memoizedCallback = useCallback(
(param1: string, param2: number) => {
console.log(param1, param2)
return { ok: true }
},
[...],
);
/**
* VSCode will show the following type:
* const memoizedCallback:
* (param1: string, param2: number) => { ok: boolean }
*/
```

Note that for React < 18, the function signature of `useCallback` typed arguments as `any[]` by default:

```ts
function useCallback<T extends (...args: any[]) => any>(
callback: T,
deps: DependencyList
): T;
```

In React >= 18, the function signature of `useCallback` changed to the following:

```ts
function useCallback<T extends Function>(callback: T, deps: DependencyList): T;
```

Therefore, the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17.

```ts
// @ts-expect-error Parameter 'e' implicitly has 'any' type.
useCallback((e) => {}, []);
// Explicit 'any' type.
useCallback((e: any) => {}, []);
```

## useReducer

You can use [Discriminated Unions](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions) for reducer actions. Don't forget to define the return type of reducer, otherwise TypeScript will infer it.
Expand Down