Do we need useReducer
?
We already have useState
which manages the state. If we look at functional level useReducer
doesn’t bring anything new to table. Both are used to store the value and manipulate it. So fundamental question is then why do even care about useReducer
?
Code readability
When we are working on a project with other member, one of the most important aspect of the code is how readable it is. I expect the code to be readable and maintainable. What I feel about useReducer
is that it makes the more readable.
Code lifecycle
What I have seen in my codebase is that, we start with simple states in the component. May be one/two useState
or a simple object to hold the state. When component grows we will have more state for the same logic, multiple handler to manipulate state and a lot of condition where we have to update the state. Even if we write the code, later in time it will be difficult to understand. It’s nightmare if it is someone else’s code.
How to organise the code
So basics things we have discussed so far is:
- State
- Updating the state
- When to update the state
useReducer
🎉
Let’s see a example and see how the code is organised.
The state
const initialTasks = [
{id: 0, text: 'Visit Kafka Museum', done: true},
{id: 1, text: 'Watch a puppet show', done: false},
{id: 2, text: 'Lennon Wall pic', done: false},
];
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
The reducer: updating the state
function tasksReducer(tasks, action) {
switch (action.type) {
case 'added': {
return [
...tasks,
{
id: action.id,
text: action.text,
done: false,
},
];
}
}
}
The dispatch: trigerring the update
function handleAddTask(text) {
dispatch({
type: 'added',
id: nextId++,
text: text,
});
}
When writing reducer
keep in mind that action types should ideally describe “what the user did” rather than “how you want the state to change”. This makes it easier to later add more features.
When we are sending the message, we need to clear the message, we could reuse the edited_message
condition and be happy, but instead react prefer to add another state, sent_message
to describe what user did.
I know we are lazy, but for a readable future let’s do it!
case 'edited_message': {
return {
...state,
message: action.message,
};
}
case 'sent_message': {
return {
...state,
message: '',
};
}