Learning React for Dummies: Hooks (Custom Hooks, useReducer)

Week 4

Hello folks,

I've decided that I need to make these blogs a little bit longer and cover more information.

This week, I'm continuing on with the last installment on Hooks.

We're going to start with Custom Hooks which sound like they would be complicated but they are actually very handy.

Custom Hooks

A custom hook allows you to import your own custom logic in the form of a reusable function. For instance, it's very common that you will be using the same component logic that's being used over multiple components, this is when creating a custom hook could come in clutch!

Example:

import { useState } from 'react'

const App = () => {

const [email, setEmail] = useState()
const [firstName, setFirstName] = useState()
const [lastName, setLastName] = useState()


return (

<>
<input name='email' value={email} onChange={e => setEmail(e.target.value)} />
<input name='first-name' value={firstName} onChange={e => setFirstName(e.target.value)} />
<input name='last-name' value={lastName} onChange={e => setLastName(e.target.value)} />
</>


)}


export default App

So here wave have three inputs and a three state values to go along with them. Now, let's turn this logic into a custom hook.

Custom hooks always start with use, for example we will use useForm for our custom hook.

import { useState } from 'react'


export const useForm = (initialValues) => {

const [values, setValues] = useState(initialValues)

return [
     values,
      e => {
          setValues({
               . . .values,
               [e.target.name]: e.target.value
          })
     }
}

I understand this may look a little confusing but let's just take a look at how we implement this into our App now.

import { useState } from 'react'

const App = () => {

const [values, handleChange] = useForm(email: '', firstName: '', lastName: '')


return (

<>
<input name='email' value={values.email} onChange={handleChange} />
<input name='first-name' value={values.firstName} onChange={handleChange} />
<input name='last-name' value={values.lastName} onChange={handleChange} />
</>


)}

Now you can see that we just took the logic of storing state and handling the onChange events and put them into our custom hook so that we can reuse this over and over again, creating as many values as we want with the handleChange function for the onChange event.

Okay, that's a pretty basic idea of how to use a basic hook, but I think you can get a pretty good idea of how that could be used in a multitude of ways.

Let's move on to our next hook.

useReducer

The useReducer hook allows for custom state logic.

You'll probably end up using it when you're trying to keep track of multiple pieces of state that rely on a lot of logic.

This hook takes in two arguments.

The reducer and initialState arguments.

The reducer argument is a function that will contain the state logic.

the initialState usually contains an object although it can contain a simple value.

We'll use useReducer in a simple counter app:

import { useReducer } from 'react'


function reducer(state, action) { 
 switch (action.type) {
     case 'increment': 
          return state + 1;
     case 'decrement':
          return state - 1;
     default
          return state
}}

const App = () => {
const [count, dispatch] = useReducer(reducer, 0)

return (
     <div>
          <div>count: {count}</div>
          <button onClick=(() => dispatch({ type: 'increment' })}>increment</button>
          <button onClick=(() => dispatch({ type: 'decrement'})}>decrement</button>
     </div>
     )
}

export default App

Here we initialized our useReducer hook with const count that holds our initial state value of 1.

We created our reducer function that will return different values to our state if either the increment or decrement button is clicked, otherwise it will just return the value of state.

This is a pretty basic example and in reality you will more than likely end up using this hook when you have a lot of logic that you want to add at the same time.

Thankfully, we are done covering hooks!

I know that I skipped over some of them but that's just because they take the most context to understand and I'm wanting to get into some more interesting content that might actually get some traffic.

I think I will probably go onto a Next.js series as I've been using that and have decided that I want to make that my go to for any production level projects in the foreseeable future.

That said, I thank you for reading and hope that you have a great rest of your day!