React Hooks with TypeScript

Function Components and Hooks in TypeScript example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// import useState next to FunctionComponent
import React, { FunctionComponent, useState } from 'react';

// our components props accept a number for the initial value
const Counter:FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
// since we pass a number here, clicks is going to be a number.
// setClicks is a function that accepts either a number or a function returning
// a number
const [clicks, setClicks] = useState(initial);
return <>
<p>Clicks: {clicks}</p>
<button onClick={() => setClicks(clicks+1)}>+</button>
<button onClick={() => setClicks(clicks-1)}>-</button>
</>
}

Hooks with TypeScript

1
2
3
const Counter:FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
...
}

with useState

1
2
3
4
5
6
7
8
9
// explicitly setting the types
const [value, setValue] = useState<number | undefined>(undefined);
const [value, setValue] = useState<Array<number>>([]);

interface MyObject {
foo: string;
bar?: number;
}
const [value, setValue] = useState<MyObject>({ foo: 'hello' });

with useRef

1
const inputEl = useRef<HTMLInputElement>(null);

with useContext

1
2
type Theme = 'light' | 'dark';
const ThemeContext = createContext<Theme>('dark');

with useReducer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
interface State {
value: number;
}

type Action =
| { type: 'increment' }
| { type: 'decrement' }
| { type: 'incrementAmount'; amount: number };

const counterReducer = (state: State, action: Action) => {
switch (action.type) {
case 'increment':
return { value: state.value + 1 };
case 'decrement':
return { value: state.value - 1 };
case 'incrementAmount':
return { value: state.value + action.amount };
default:
throw new Error();
}
};

const [state, dispatch] = useReducer(counterReducer, { value: 0 });

dispatch({ type: 'increment' });
dispatch({ type: 'decrement' });
dispatch({ type: 'incrementAmount', amount: 10 });

// TypeScript compilation error
dispatch({ type: 'invalidActionType' });