React Hooks

ยท

4 min read

React Hooks? What are they? This is one question I took some time to get an answer to when I first started learning React. When I first heard of them I was a bit scared, but with time I came to understand them. So in this article, I am going to explain them.

So what are react Hooks?

React hooks are JavaScript functions that allow us to use React features, e.g. state without having to write a class. They provide a way to use stateful logic in functional components.

Hooks don't work with classes

Hooks are only called at the top level of the components and not inside loops, conditions and nested functions.

Examples of hooks

  • useState

  • useEffect

  • useContext

  • useReducer

  • useCallback

  • useRef

In this article, I am going to discuss useState, useEffect, useContext and useReducer. Let's understand them:

useState

This hook allows functional components to have a state. It accepts an argument which is the initial value of the state. It returns an array with two elements: the current state value and a function to update this state. Example:

We are going to use the UseState hook to manage the state of our count variable

// start by importing 
import { useState } from 'react'
// To use it, call it since a hook is just a function

function CountComponent () { 
// initial value of count is 0
const [count, setCount] = useState(0)
return (
    <>
        <button onClick=(() => {setCount(count + 1)})>{count}</button>    
    </>
)
}

useEffect

This hook is used to perform side effects in functional components. Side effects are any code that interacts with the outside world, e.g. modifying the DOM, fetching data from an API, setting timers, etc. They allow us to interact with external resources.

UseEffect accepts two arguments: callback and dependencies

  • The callback is a function that is executed after every render of the component.

  • Dependencies is an optional array of dependencies, useEffect executes a callback only if the dependencies have changed, i.e. it helps you control when the side-effect runs.

Example: We are going to use useEffect to fetch data from an API

// start by importing 
import { useEffect, useState } from 'react'
// To use it, call it since a hook is just a function

function CountComponent () { 
// initial value of dat is an empty array
const [data, setData] = useState([])

useEffect(() => {
    // fetch data from API
    fetch(APIurl)
        .then((res) => res.json())
        .then((data) => setData(data))  
        .catch((error) => console.log(error))  
}, []) // this empty dependency array only runs the effect once
return (
    <>
        <button onClick=(() => {setCount(count + 1)})>{count}</button>    
    </>
)
}

Let us understand dependencies more :). As it is optional, dependencies can either be provided or not.

  • When not provided, side-effect runs after every rendering.

  • When it is an empty array, the side-effect runs once after the initial rendering.

When it has values, the side-effect runs once after the initial rendering and when the value in the dependency array changes.

useContext

This hook provides a means to pass down data through the component tree without having to pass props down manually at every level

To understand this hook I am going to show you an example:

First, we have to create a context instance:

// context.js
import { createContext } from 'react'

export const UserContext = createContext()

Secondly, provide the context to the child components:

// App.js
import UserContext from './context'

function App () {
return (
    <UserContext.Provider value="Jean"> //set value of context
        <Component />
    </UserContext.Provider>
)
}

Any component that needs to access the context value must be wrapped inside the provider component.

Lastly, we have to consume the context:

// Component.js
import { UseContext } from 'react'
import UserContext from './context'

function Component () {
const value = useContext(UserContext)
return (
    <h3>{value}</h3>
)

}

useReducer

This hook is used for state management and is an alternative to useState, but useReducer is preferable when you have complex state logic. It accepts two arguments: reducer function and initialState.

The reducer function accepts the current state and an action and returns a new state.

UseReducer then returns an array of two items: current state and dispatch function, this dispatches an action to update the state*.*

import { useRedcer } from 'react'

const initialState = 0;

function reducer (state, action) {
    switch (action.type) {
        case 'increment':
            return state + 1
         case 'decrement':
            return state - 1
    }
}
function Component() {
const [count, dispatch] = useReducer(reducer, initialState)
return (
    <>
        <button
            onClick={() => dispatch({
            type: 'increment'})}>Increment
        </button>

        <button
            onClick={() => dispatch({
            type: 'decrement'})}>Decrement
        </button>
    </>
)
}

That is all for this article. I hope it helped you. Thanks for reading this far. My appreciation goes out to React Docs.