Lets, check react advanced hooks, i.e. UseCallback, UseMemo, UseRef, and UseContext. All these come under React 16.8 version and help the user create an optimized react application.

Let’s create a react application environment for our project by using either of the following commands:

1.yarn create react-app advanced-hooks-tutorial --template typescript
 # or 
2.npx create-react-app advanced-hooks-tutorial --template typescript

The above command will create a Project with the name “advanced-hooks-tutorial”. Once it’s done go to the directory and start the project either by “npm start” or “yarn start”.

We will be using yarn throughout this tutorial to maintain consistency.

Let’s now integrate the project with antd which is a design library by the name of antd design, that helps us to create some standard UI components. Additionally, you can use other design libraries as well if you want.

  1. Add antd to dependency
# terminal

yarn add antd

2. Add antd CSS to load stylings

# src/index.tsx

...
import 'antd/dist/antd.css';
...

That’s all for our project base, we have successfully integrated react hooks with antd design library.

UseCallback

UseCallback takes two arguments- In the first argument it takes an inline function that is called callback and in second arguments it takes an array of dependencies on which the callback function depends and returns a memoized callback.

The memoized callback changes only when one of its dependencies is changed. This is useful to optimize the child components that use the function reference from their parent component to prevent unnecessary rendering.

# syntax 

const memoizedCallback = useCallback(() => performSomething(param1, param2 ,...),[param1, param2, ...]);

Let’s see an example for this – Here, we are going to create an app consisting of two-buttons which will increment the age and salary of a person.

  • Create a file AdvancedHooksComponent.tsx in src/components directory- create the directory if not available there.
  • Now create a functional component, ie. AdvancedHooksComponent and import the component in App.tsx file.
# src/components/AdvancedHooksComponent.tsx

import React from 'react';

interface Props {
};

const AdvancedHooksComponent: React.FC<Props> = () => {

    return (
        <div>
            Advanced Hooks Component
        </div>
    );
};

export default AdvancedHooksComponent;

After this, your App.tsx file would look like :

# src/App.tsx

import React from 'react';
import './App.css';
import AdvancedHooksComponent from "./components/AdvancedHooksComponent";

const App: React.FC = () => {
  return (
    <div className="App">
        <AdvancedHooksComponent/>
    </div>
  );
};

export default App;

Now let’s add two child Button component named- AgeButton, SalaryButton, and a Title component. Import them in AdvancedHooksComponent.tsx.

# src/components/AdvancedHooksComponent.tsx

import React,{useState} from 'react'
import AgeButton from './AgeButton'
import SalaryButton from './SalaryButton'

interface Props {
};

const AdvancedHooksComponent: React.FC<Props> = () => {

    const [age, setAge] = useState(12);
    const [salary, setSalary] = useState(5000);
   
    const ageHandler = ()  => {
            setAge(age+1);
        };

    const salaryHandler = () => {
            setSalary(salary+500);
        };

    return (
        <div>
            <h1>Use CallBack Example</h1>
            <AgeButton clickHandler={ageHandler} age={age}/>
            <SalaryButton clickHandler={salaryHandler} salary={salary}/>
        </div>
    );
};

export default AdvancedHooksComponent;

We have used the useState hook to create state variables, i.e. age and salary and their corresponding dispatcher, ie. setAge and setSalary. Learn How to create State Variables.

AgeHandler and SalaryHandler are two inline functions that increment the age and salary on every click of AgeButton and SalaryButton respectively.

Note: If you don’t know how to use useState then you can refer our blog from here:- React Hooks With Typescript.

AgeButton component looks like :

# src/components/AgeButton.tsx

import React from "react";
import {Button} from "antd";

interface Props {
    clickHandler : () => void;
    age : number
}

const AgeButton = ({ clickHandler, age } : Props  ) => {
    console.log("Age Button Rendered Age = " + age)
    return (
        <Button onClick={clickHandler} type="primary" style={{ margin : 2}}>Increment Age</Button>
    )
};

export default React.memo(AgeButton);

SalaryButton component looks like :

# src.components/SalaryButton.tsx

import React from "react";
import {Button} from "antd";


interface Props {
    clickHandler : () => void;
    salary : number;
}

const SalaryButton = ({ clickHandler, salary } : Props ) => {
    console.log("Salary Button Rendered Salary = " + salary)
    return (
        <Button onClick={clickHandler} type="primary" style={{ margin : 2}}>Increment Salary</Button>
    )
};

export default React.memo(SalaryButton);

We have a console statement in both the AgeButton and SalaryButon that will help us in understanding the concept of useCallback hook later in the project.

Note: AgeButton and SalaryButton components are wrapped in the React.memo function which is a higher-order function. You can learn more about this from here:- React Memo.

Now start the app using the below command:

  yarn start

You will see the following output in the console:

Read More:   UI/UX Design company pick: Sketch vs. Figma vs. Zeplin

As you can see in the web console, the rendering order of child component- first AgeButton component render and then SalaryButton component render.

Now, if we click on the increment Age Button then age will be incremented and react will re-render the component because if state changes then the component re-renders.

So the output looks like :

As you can see in the console- The AgeButton component re-render and age become 13, which is correct but the SalaryButton component also re-render and that is not necessary because we updated the age only and not salary.

So to fix this problem, useCallback comes into the picture:

We have to pass the ageHandler and salaryHandler function in the useCallback hook, so that memoized callback returns and changes only when passed dependencies changed.

For ageHandler- the only dependency is age and for salaryHandler- salary is the only dependency.

# src/components/AdvancedHooksComponent.tsx

import React, {useCallback, useState} from 'react';
import AgeButton from "./AgeButton";
import SalaryButton from "./SalaryButton";

interface Props {

}

const AdvancedHooksComponent: React.FC<Props> = () => {

    const [age, setAge] = useState(12);
    const [salary, setSalary] = useState(5000);


    const ageHandler = useCallback(()  => {
        setAge(age+1);
    }, [age])


    const salaryHandler = useCallback( () => {
        setSalary(salary+500);
    }, [salary])


    return (
        <div>
            <h1>UseCallBack Example</h1>
            <AgeButton clickHandler={ageHandler} age={age}/>
            <SalaryButton clickHandler={salaryHandler} salary={salary}/>
        </div>
    );
};

export default AdvancedHooksComponent;

Now, if I click on the increment age button only the AgeButton component will re-render.

As you can see in the console only the AgeButton component is re-rendered. So this is how useCallback helps in preventing unnecessary rendering.

UseMemo

This hook will return a memoized value.

Suppose you have to compute a value that requires complex computation like fetching the list of 500 people from a database and then map over the list and then filter some person and finally update on the UI.

This operation is costly and recomputes after every rerender.

Using useMemo, we can simplify the process and this operation is performed only once and the value is stored in the cache. And the next time you want it, you’ll get it much faster.

# syntax

const memoizedValue = useMemo( () => costlyOperation(param1 , param2, ...) , [param1, param2, ...]);

The syntax of useMemo is similar to useCallback, but both work differently- useCallback returns a memoized callback(or function), on the other hand useMemo returns a memoized value (the result of the memoized callback).

Let’s see an example for this, where I made some modifications in AdvancedHooksComponent.tsx file :

# src/components/AdvancedHooksComponent.tsx

import React, {useCallback, useState} from 'react';
import AgeButton from "./AgeButton";
import SalaryButton from "./SalaryButton";

interface Props {
}

const AdvancedHooksComponent: React.FC<Props> = () => {

    const [age, setAge] = useState(12);
    const [salary, setSalary] = useState(5000);


   const notMemoizedValue = () => {
        // some complex computation work here..
        let i = 0;
        while (i < 2000000000) i++;

        // after while break then do something here
        if(age % 2 === 0) return "Even";
        else return "Odd";
      }


    const ageHandler = useCallback(()  => {
        setAge(age+1);
    }, [age])


    const salaryHandler = useCallback( () => {
        setSalary(salary+500);
    }, [salary])


    return (
        <div>
            <h1>UseMemo Example</h1>
            <h3>{notMemoizedValue()}</h3>
            <AgeButton clickHandler={ageHandler} age={age}/>
            <SalaryButton clickHandler={salaryHandler} salary={salary}/>
        </div>
    );
};

export default AdvancedHooksComponent;

We have the “notMemoizedValue” function, which will check whether the current age is even or odd but we need some computational work to do before checking odd or even.

For simplicity, we will make a while loop that takes some time (which behave as complex computation like fetching data from database and so on). After the while loop breaks, the odd-even checking statement executes.

The result of “notMemoizedValue” function will be displayed on the UI.

So, as you can see our “notMemoizedvalue” function returns an even value but this value is not memoized value because if we press the increment salary button then the salary will be incremented. And after this rerendering occurs which leads to the recomputation of the “notMemoizedValue” function value that remains unchanged because age doesn’t change only the salary gets changed. Apart from this, you might feel some delay also.

So, Using useMemo we can return a memoized value of the “notMemoizedValue” function which saves the time from recomputation.

Read More:   Top Android Frameworks and Libraries for App Development in 2022

Using useMemo the code will look like :

# src/components/AdvancedHooksComponent.tsx


import React, {useCallback, useMemo, useState} from 'react';
import AgeButton from "./AgeButton";
import SalaryButton from "./SalaryButton";

interface Props {
}

const AdvancedHooksComponent: React.FC<Props> = () => {

    const [age, setAge] = useState(12);
    const [salary, setSalary] = useState(5000);


    const memoizedValue =  useMemo( () => {
        // some complex computation work here..
        // for simplicity I wrote while loop here 
        let i = 0;
        while (i < 2000000000) i++;

        // after while break then do something here
        if(age % 2 === 0) return "Even";
        else return "Odd";

    } , [age])

    const ageHandler = useCallback(()  => {
        setAge(age+1);
    }, [age])


    const salaryHandler = useCallback( () => {
        setSalary(salary+500);
    }, [salary])


    return (
        <div>
            <h1>UseMemo Example</h1>
            <h3>{memoizedValue}</h3>
            <AgeButton clickHandler={ageHandler} age={age}/>
            <SalaryButton clickHandler={salaryHandler} salary={salary}/>
        </div>
    );
};

export default AdvancedHooksComponent;

Simply, remove the “notMemoizedValue” function with “memoizedValue” function and save the file.

Now, if you again press the increment salary button then the memoized value of Odd-Even will be return by the “memoizedValue” function and now this time you do not feel any delay.

UseRef

Using useRef Hook, we can access the DOM nodes or HTML elements as we access in vanilla javascript via “document” object, so that we can interact with those DOM nodes.

# syntax

const nameRef = useRef(initialValue);

useRef hook takes an initial value and returns a mutable object (a mutable object means the object whose state can be changed after it is created).

The return ref object holds a mutable value in its current property which will remain the same on every rerender.

Let’s do an example for this: In the same file AdvancedHooksComponent, let’s create an input element- :

# src/components/AdvancedHooksComponent.tsx

import React, { useEffect, useRef} from 'react';

interface Props {
}

const AdvancedHooksComponent: React.FC<Props> = () => {

    const inputRef = useRef<HTMLInputElement>(null);

    useEffect(() => {

        if(inputRef && inputRef.current) {
            inputRef.current.focus();
        }

    }, [])


    return (
        <div>
            <h1>UseRef Example</h1>
            <input type="text" ref={inputRef} style={{width : '40%'}}/>
        </div>
    );
};

export default AdvancedHooksComponent;

As you can see, we have an inputRef object containing initial value as null which gets passed in the input ref attribute.

Now, save the file and go to your browser- You will see that your input field is focused and you can do other things as well, as you do in vanilla javascript by “document” object.

Note: useRef does not notify you when it’s content value changes. Also changing useRef current value doesn’t lead to re-render.

UseContext

To understand the concept of useContext hook– First we have to understand what is React Context API?

React Context API helps us to pass the data down to the child components (which depends on parent for data) from the root or parent component, instead of manually passing the data to every component by using props.

Let’s look at the below picture :

Suppose, we have three above components in our project and we want to pass the username of a user from AppComponent to UserComponent without using HomeComponent in between:-

App.tsx looks like :

# src/App.tsx

import React from 'react';
import './App.css';
import HomeComponent from "./components/HomeComponent";

export const UserContext = React.createContext('');

const App: React.FC = () => {
    
    const value : string = "Codersera";

  return (
    <div className="App">
        <UserContext.Provider value={value}>
            <HomeComponent/>
        </UserContext.Provider>
    </div>
  );
};

export default App

Here, we used React.createContext API to create a Context with an empty string as the initial value. It returns two components Provider and Consumer. Learn about API.

Provider: It is used to pass the data down to the child components.

Consumer: It is used to consume the data passed by the Provider component.

Note: If you don’t use useContext hook, then you can use the Consumer component. But here we use, useContext hook for consuming the data which makes the code less and more readable.

Provider component takes an attribute called “value” through which we can pass the data down. To use the passed data value, components should be wrapped inside the UserContext component.

# src/components/HomeComponent.tsx

import React from 'react';
import UserComponent from "./UserComponent";

const HomeComponent = () => {
    return (
        <UserComponent/>
    );
};

export default HomeComponent;

HomeComponent simply just renders UserComponent.

# src/components/UserComponent.tsx

import React, { useContext} from 'react';
import { UserContext } from '../App'


const UserComponent = () => {
    const username = useContext(UserContext);
    return (
        <div>
            <h1>UseContext</h1>
             <div>{username}</div>
        </div>
    );
};

export default UserComponent;

UserComponent uses the passed data value- First it imports the UserContext Object from App.tsx file, then passes this object in the argument of useContext hook (which returns the passed data value), as we have used inside the div tag.

Read More:   Creating A Payment App That Meets All Your Requirements

The output of the above code looks like :

That’s it. We have successfully used useCallback, useMemo, useRef, and UseContext.

Source: InApps.net

List of Keywords users find our article on Google:

react advanced questions
antd
command hooks
react useref
usecontext
useref
command strips
command hook
antd react
useref react
react hook
devops salary
react advanced search component
react memo
onclick react
ecommerce salary
react advanced search
useref vs usecontext
react data export
react phone number input
antd icons
react onclick
react hooks
react hooks tutorial
yarn create react app
ui design salary
create react app typescript
usecontext useref
qa salary
antd table
antd select
useref hook
ui ux salary
react usecontext
command picture hooks
react callback
usestate callback
react native hooks
usememo vs useref
import manager salary
react usestate callback
what is setpay
antd icon
usecontext react
hook productivity
how to command hooks
react tag input
react.fc
ui ux design salary
h1 communication
initial hooks
react.memo
usestate in react js
hooks in react js
react render
classname react native
advanced search react
create react
react app template typescript
react props
for loop in react
react custom hooks
react game tutorial
react ref
usestate object
offshore php development
useref and usecallback
useref vs usecallback
useref callback
usecallback react hooks
wawa salary
npm antd
hire hooks developer
antd center
offshore salary
react scheduler component
functional consultant salary
value labs salary
react scheduling component
valuefirst whatsapp
antd components
erp project manager salary
useref example
antd tag
computational design salary
readable array react native
antd list
antd react native
antd react table
react-phone-input-2
thewebconsole
antd mobile
antd template
advanced custom fields hooks
useconext
angularjs salary
render unnecessary
command strips hooks
react rerender
uiux salary
antd upload
react phone number input 2
react useeffect only once
antd input
antd text field
antd table search
food product development salary
ux design consultant salary
menu antd
create react portfolio
textinput ref react native
antd js
create react app antd
custom tsx
import usecontext
onclick function react
design lead salary
hospitality designer salary
object in state react
useeffect without dependency array
84 console table
h1 salary
hire vanilla js developers
hook and loop game
react button onclick
react hooks version
suppose design office
tsx value
antd next js
next js antd
react classname
react usecontect
typescript react template
react form hooks
react template for ecommerce
react website templates
search button react
usestate with object
create react app youtube
import css in react
pass function as props react
react native input field
useref.current
antd with next js
project div
react pass ref to child
react typescript return array of components
“…props” react
create react app node 12
export react app
react loop through array
react typescript table component
tsx file
how to remove command hooks
import button react
react empty tag
react native hooks tutorial
useeffect syntax
when does react rerender
button onclick react
create react app typescript yarn
react product filter
react ref hook
login with react hooks
react app template
react hooks this
create react app with typescript
create react app yarn
food app design template
hook reactjs
hook useref
how to create react hooks
npx create react app
ui and ux design salary
wrapped memo
yarn create react app typescript
custom hook react
hooks game schedule
npx create react app typescript
pass callback to child component react
pass data to child component react
react functional components props
this in react hooks
api react hooks
create react app templates
how does usecontext work
picture hook hangers
react create app typescript
react css props
react filter component
react input
usestate import
react function get props
react pass data from child to parent
use hooks in react
recomputation
recomputes
hooks api reference
react native development services
Rate this post

Let’s create the next big thing together!

Coming together is a beginning. Keeping together is progress. Working together is success.

Let’s talk

Get a custom Proposal

Please fill in your information and your need to get a suitable solution.

    You need to enter your email to download

      [cf7sr-simple-recaptcha]

      Success. Downloading...