react.dev
react.dev copied to clipboard
[Question - Beta docs] Is there TypeScript version of examples?
Hi, I was looking at basic useReducer examples in the beta version of React docs and am wondering if there's TypeScript version of them.
In my opinion, it would be a great addition if it doesn't exist yet. Thanks in advance!
Not at the moment, but we'd like to make an effort to add that. Requires solving some technical challenges.
@kevinadhiguna
I can try and provide an example! Maybe if a senior dev reads this they might have some corrections, however:
Typescript's main feature is it's static type system.
Basically, what STS means is that when we compile our code, variables must already have their types (boolean, string) defined.
When we analyze the JavaScript code in the example you asked about we see:
- A function including the hook;
useReducer. This will affectage, by incrementing whatever number is received as input.nameis changed according to user input:
function reducer(state, action) {
switch (action.type) {
case 'incremented_age': {
return {
name: state.name,
age: state.age + 1
};
}
case 'changed_name': {
return {
name: action.nextName,
age: state.age
};
}
}
throw Error('Unknown action: ' + action.type);
}
- A React component that introduces 2 objects,
name: Taylor and age: 42
const initialState = { name: 'Taylor', age: 42 };
- Callback functions,
handleButtonClickandhandleInputChange, which respond to the changes by useReducer to name and age by updating the screen. Likewise, includingdispatchwill allow for re-renders for states.
export default function Form() {
const [state, dispatch] = useReducer(reducer, initialState);
function handleButtonClick() {
dispatch({ type: 'incremented_age' });
}
function handleInputChange(e) {
dispatch({
type: 'changed_name',
nextName: e.target.value
});
}
- A return function:
return (
<>
<input
value={state.name}
onChange={handleInputChange}
/>
<button onClick={handleButtonClick}>
Increment age
</button>
<p>Hello, {state.name}. You are {state.age}.</p>
</>
);
}
Converting the aforementioned to Typescript would look something like this:
import { useReducer } from 'react';
type State = { name: string, age: number };
type Action =
| { type: 'incremented_age' }
| { type: 'changed_name', nextName: string };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'incremented_age': {
return {
name: state.name,
age: state.age + 1
};
}
case 'changed_name': {
return {
name: action.nextName,
age: state.age
};
}
default: throw Error('Unknown action: ' + action.type);
}
}
const initialState: State = { name: 'Taylor', age: 42 };
export default function Form() {
const [state, dispatch] = useReducer(reducer, initialState);
function handleButtonClick() {
dispatch({ type: 'incremented_age' });
}
function handleInputChange(e: ChangeEvent<HTMLInputElement>) {
dispatch({
type: 'changed_name',
nextName: e.target.value
});
}
return (
<>
<input
value={state.name}
onChange={handleInputChange}
/>
<button onClick={handleButtonClick}>
Increment age
</button>
<p>Hello, {state.name}. You are {state.age}.</p>
</>
);
}
In any case, you might benefit from going example by example and working on re-writing each component with Typescript as an exercise. I might do the same!
@kevinadhiguna I think this site will help you. React TypeScript Cheatsheet #usereducer