Additional Hooks in React – useReducer()

Additional Hooks in React – useReducer():

What is useReducer()?

useReducer() is JavaScript function, which allows to use reducer functions from state management in functional component. It is an alternative to useState() hook and as react developers say : “New one and improved” 🙂

Before you read any further, you should be familiar with state management and reducers.

How and when use useReducer()

To use this hook, you need to import it first from React library like this:

import {useReducer} from 'react';

You can use this hook without import as well like this – React.useReducer(), for me it’s just more convenient to import and destructure first this function and then use it when need in the code.

Afterwards we can set up this hook like this:

const  [state, dispatch] = useReducer(reducer, initialState);

Let’s examine this example more detailed.

NOTE: If you are familiar with Redux, you already know how it works

useReducer hook :

  • accepts reducer function and initial state.
  • returns current state and dispatch method

Let’s consider the following example – we are building an app which is a simulation of the farm.

Here’s a store of data, where we have four hungry animals (this is our initialState):

const animals = [
  {type: 'horse', isHungry: true},
  {type: 'sheep', isHungry: true},
  {type: 'cow', isHungry: true},
  {type: 'pig', isHungry: true}
]

Let’s create a reducer to feed them:

const animalsReducer = (animals, action) => {

  if(action.type == 'feed') {
    return animals.map(animal => {
      if(animal.type == action.specificAnimal) {
        animal.isHungry = false;
      }
      return animal;
    })
  }
  if(action.type == 'giveWater') {
    return animals.map(animal => {
      if(animal.type == action.specificAnimal) {
        animal.isHungry = true;
      }
      return animal;
    })
  }
}

So, the important thing to notice here is what we pass to our animalsReducerfunction: our initial state (animals) and action (you could think of this as a setState method). The action.type identifies what type of action we want to do and action.specificAnimal identifies for us which animal we want to perform the action on.

Now that we have our reducer and store setup, let’s implement them with our useReducer() hook:

const [state, dispatch] = useReducer(animalsReducer, animals);

And finally let’s implement our dispatch functions and use them in JSX:

const feed =(animalType)=>{dispatch({ type: 'feed', specificAnimal: animalType });}

const giveWater = (animalType) => {dispatch({ type: 'giveWater', specificAnimal: animalType });}

return (
  
{state.map((animal, idx) => (
{animal.type}
{animal.isHungry ?
NOT HUNGRY! feed(animal.type)}> feed
:
HUNGRY giveWater(animal.type)}> give water
}
))}
)

The dispatch method receives an object that represents the action we desire to be done. We pass our action to our reducer through the useReducer. Our reducer returns updated state.

CONCLUSION

You can use useState in the same component or hook that’s using useReducer and you can have multiple useStates and multiple useReducers in a single hook or component.
useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. 
useReducer also lets you optimize performance for components that trigger deep updates because you can pass dispatch down instead of callbacks.

from Tumblr https://generouspiratequeen.tumblr.com/post/640805936329555968

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s