Published on

What is useReducer? What it does and seeing the beauty of that React Hook.

Authors

Title: Learn useReducer

Author: Alejo G.B

Subject: React | Frontend Development

Language: English

Resource used to make this article: Pure React

Learn useReducer()

Reduce the number of states you have in your app. Reduce, remember this. Convert 2 values into 1. In other words, take two or more states and convert them into one.  This is what the useReducer hook is about.

So how useReducer can be used? You can see it as instead of using multiple useState for various states, you could use only one, by creating a useReducer with actions to it.  As the official React blog recommends: "An alternative to useState." (I recommend you to first read from the React guys and then come here). However, I don't like the example that's being given there, because it showcases a counter application, which by definition has only two possible actions (increase and decrease). What I want to show you, is how I found these hooks somehow useful.

Example by refactoring

const [good, setGood] = useState(0)
const [neutral, setNeutral] = useState(0)
const [bad, setBad] = useState(0)
const handleGood = () => {
setClicks(clicks +1)
setGood(good +1)
}
const handleBad = () => {
setClicks(clicks +1)
setBad(bad +1)
}
const handleNeutral = () => {
setClicks(clicks +1)
setNeutral(neutral +1)
}
const Button = ({handleBad, handleGood, handleNeutral}) => {
return(
<>
<button onClick={handleGood}>Good</button>
<button onClick={handleBad}>Bad</button>
<button onClick={handleNeutral}>Neutral</button>
<p>Good: {good} | Neutral : {neutral} | Bad : {bad}</p>
</>
)

Starting with this example, which is part of one exercise of the fullStack Open curriculum. This a feedback app for a restaurant. Or a customer tool to rate some other service. You can vote on good, neutral, or bad. You can see the live code working here: https://codesandbox.io/s/feedback-react-i8up0 To not go so deep in this, I'll just jump into what it would like refactored to useReducer.

const initialState = { bad: 0, good: 0, neutral: 0 }
const reducer = (state, action) => {
const { good, bad, neutral } = state
switch (action.type) {
case 'good':
return {
...state,
good: good + 1,
}
case 'neutral':
return {
...state,
neutral: neutral + 1,
}
case 'bad':
return {
...state,
bad: bad + 1,
}
}
}
const [state, dispatch] = useReducer(reducer, initialState)
return (
<>
<button onClick={() => dispatch({ type: 'good' })}>Good</button>
<button onClick={() => dispatch({ type: 'bad' })}>Bad</button>
<button onClick={() => dispatch({ type: 'neutral' })}>Neutral</button>
<p>
Good: {state.good} | Neutral : {state.neutral} | Bad : {state.bad}
</p>
</>
)

Another thing I've noticed is that useReducer can be set in the same file as the component. While with redux you need to put a whole new folder and file to set the store.   This is what a useReducer looks like:

const [todos, dispatch] = useReducer(reducer, [])

You can see that it takes place only in the component And this is what a redux folder structure looks like:

/redux
/actions
/reducer
store.js