Sagar Medtiya
Sagar Medtiya

Sagar Medtiya

Understanding the basics of React Hooks🪝

Understanding the basics of React Hooks🪝

Sagar Medtiya's photo
Sagar Medtiya
·Aug 9, 2022·

6 min read

Subscribe to my newsletter and never miss my upcoming articles

Play this article

Table of contents

  • What are hooks🪝?
  • Basic hooks
  • Additional hooks
  • Resources

What are hooks🪝?

Hooks are new added features in React⚛️ 16.8. It is a way to use state and other React features like managing your component's state, or performing an after effect when certain changes occur in state without writing a class.

Basic hooks

useState:

It is a common hook used to create state variable in a functional component.

Syntax:

const [state, setState] = useState(initialState);

useState accepts an initial state and returns 🥈 values:

  • The current state.
  • A function that updates the state.

For example,

import { useState } from "react";

function App() {
  const [name, setName] = useState("TheSagar");
  const changeName = () => {
    setName("Sagar");
  };

  return (
    <div>
      <p>My name is {name}</p>
      <button onClick={changeName}> Click me </button>
    </div>
  );
}

export default App;

Let's take a look👁️‍🗨️

I have imported useState hook🪝 and used functional component called app. The state variable is called name, and setName is the function for updating its value.

useEffect:

The useEffect Hook🪝 allows you to perform side effects in your components.

Some examples of side effects are: fetching data, directly updating the DOM, and timers.

useEffect accepts two arguments. The second argument is optional.

useEffect(<function>, <dependency>)

import { useState, useEffect } from "react";

function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`You have clicked the button ${count} times`)
  }, []);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

export default App;

Here's an example of useEffect, which runs for only once because we are passing empty array as dependency array.

when to use it?

It has lots of use cases but let me mention the most common one.

  • use it as the initial first render of the component (ComponentDidMount).
  • use it when a component goes out of scope (ComponentWillUnMount)
  • to call or handle any piece of code for a particular state change.

useContext

The React⚛️ Context API is a way for a React app to effectively produce global variables that can be passed around. This is the alternative to "prop drilling" or moving props from parent to child.

without-context-and-with-context.webp

As you can see, that in without context API if you want to pass the data to the last child component then you have to pass to it every child component. This process is called props drilling. But with context API you can directly pass data (props) to any child👶 component.

How it works?

To create the global🌐 variable React.createContext() is all you need. Provider is a component that as it's names suggests provides the state to its children. It will hold the "store" and be the parent of all the components that might need that store. Consumer as it so happens is a component that consumes and uses the state.

Let's see the example,

import { createContext, useContext } from "react";

const UserContext = createContext();
const user = 'Rashmika Mandanna'
function Component1() {
  return (
    <UserContext.Provider value={user}>
      <h1>{`Hello ${user}!`}</h1>
      <Component2 />
    </UserContext.Provider>
  );
}

function Component2() {
  return (
    <>
      <h1>Component 2</h1>
      <Component3 />
    </>
  );
}

function Component3() {
  return (
    <>
      <h1>Component 3</h1>
      <Component4 />
    </>
  );
}

function Component4() {
  return (
    <>
      <h1>Component 4</h1>
      <Component5 />
    </>
  );
}

function Component5() {
  const user = useContext(UserContext);
  return (
    <>
      <h1>Component 5</h1>
      <h2>{`Hello ${user} again!`}</h2>
    </>
  );
}

export default Component1;

As you can see, we directly passed the user variable to Component5 with the help of useContext hook.😍

Additional hooks

useReducer:

The useReducer Hook is similar to the useState Hook. It allows for custom state logic. If you find yourself keeping track of multiple pieces of state that rely on complex logic, useReducer may be useful.

The useReducer Hook accepts two arguments.

useReducer(<reducer>, <initialState>)

The hook then returns an array of 2 items: the current state and the dispatch function.

For example,

import React,{useReducer} from 'react';
const reducer = (initialState,dispatch)=>{
    const {type,payload} = dispatch;
    switch(type){
        case 'INC':
            return initialState + payload;
        case 'DEC':
            return initialState - payload;
        dafault:
            return initialState;
    }

}
const Parent=()=>{
    const [count,countDispatcher] =useReducer(reducer,0);
    return <div>
        <button onClick={()=>{
            countDispatcher({type:'DEC',payload:2})
        }}>Decrease</button>
        <div>{count}</div>
        <button onClick={()=>{
            countDispatcher({type:'INC',payload:2})
        }}>Increase</button>
    </div>
}

export default Parent

Output

Screenshot 2022-08-10 220041.png

Let's take a look👁️‍🗨️

Here we have implemented useReducer hook logic. Then we pass that reducer to the useReducer as the first parameter and pass ‘0’ as the initial value. And now we can increase or decrease the count value using countDispatcher.😊

useCallBack

The useCallBack hook returns memoized callback function. Think of memoization as caching a value so that it does not need to be recalculated. The reason to use this hook is to prevent a component from re-rendering unless its props have changed. It only runs when one of its dependencies update.

For example,

import React, {useCallback} from 'react';
const Parent=()=>{
    return (
        <>
        {(new Array(2).fill(0).map(()=><Child/>))}
        </>
    )   
}
const Child=()=>{
    const memoizedFunction = useCallback(()=>{
        console.log('Hello Viewers')
    },[])
    return <div onClick={()=>memoizedFunction()}>Child component</div>
}

export default Parent

Output

Screenshot 2022-08-10 225028.png Let's take a look👁️‍🗨️

“memoizedFunction” will not create a new reference on every render.

useRef

The useRef Hook allows you to persist values between renders. It returns a mutable ref object. This object has a property called .current. These values are accessed from the current property of the returned object. The .current property could be initialised to the passed argument initialValue e.g. useRef(initialValue). A common use case is to access dom/ child component properties.

Syntax

const refContainer = useRef(initialValue);

For example,

import React, {useRef, useEffect} from 'react';
const Parent=()=>{
      const first = useRef({hello:'hello'});
      const item = useRef(null);
      useEffect(()=>{
        console.log('firstRef', first);
        console.log('ChildRef', item);
        item.current.style.color = 'green'
      })
      return <p ref={item}>Paragraph</p>
}

export default Parent

Output

Screenshot 2022-08-11 000546.png

Screenshot 2022-08-11 000834.png As you can see in the code and output useRef just store the value or property of the DOM/ React Component which you can also change.

Custom Hooks

Custom React hooks are an essential tool that let you add special, unique functionality to your React applications. In many cases, if you want to add a certain feature to your application, you can simply install a third-party library that is made to solve your problem. But if such a library or hook doesn't exist, what do you do? You create one!

import {useState, useEffect} from 'react'

const useMobileView =()=>{
    const [isMobile, setIsMobile] = useState(false);

    useEffect(()=>{
        window.addEventListener('resize',(event)=>{
            setIsMobile(window.innnerWidth >768 ?true:false);
        });
        return ()=> window.removeEventListener('resize',(event)=>{});
    },[])
    return isMobile;;
}

export default useMobileView;

./useMobileView.js

import React,{useEffect,useState,useLayoutEffect} from 'react';
import useMobileView from './useMobileView';

const HelloComponent =()=>{
    const isMobile = useMobileView();

    return <p>Screen View:{JSON.stringify(isMobile)}</p>
}

export default HelloComponent

./HelloComponent.js

Suppose you want a state by which you can figure out either the screen is in mobile view or desktop view.

Note: you have to use ‘use’ as a prefix for the service name as you can see in the code.

Resources

That's it! Thanks for reading this article. I hope you have enjoyed it.

Did you find this article valuable?

Support Sagar Medtiya by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
 
Share this