React 101 – Part 5: Introduction to React Hooks – A Comprehensive Guide to Building Modern User Interfaces

Hey Tech Geeks!

Hope you are doing good. Let’s talk about React Hooks

React has built-in Hooks and you can also combine them and build your own Hook

Let’s list down the built-in Hooks that we are going to discuss today.

  • State Hooks
  • Context Hooks
  • Ref Hooks
  • Effect Hooks
  • Performance Hooks
  • Resource Hooks

State Hooks : React Hooks

A component’s state allows it to “remember” information such as user input. We have a UserInputForm component that uses the useState hook to manage the state of the ‘name’ and ’email’ input fields, allowing users to supply their name and email, and a handleSubmit method for processing form submissions in the accompanying React code snippet.

Use one of the following Hooks to add state to a component:

import React, { useState } from 'react';

function UserInputForm() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');

  const handleNameChange = (e) => {
    setName(e.target.value);
  };

  const handleEmailChange = (e) => {
    setEmail(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    // You can perform actions with the name and email values here.
    console.log(`Submitted Name: ${name}, Email: ${email}`);
  };

  return (
    <div>
      <h2>User Input Form</h2>
      <form onSubmit={handleSubmit}>
        <label>
          Name:
          <input type="text" value={name} onChange={handleNameChange} />
        </label>
        <br />
        <label>
          Email:
          <input type="email" value={email} onChange={handleEmailChange} />
        </label>
        <br />
        <button type="submit">Submit</button>
      </form>
    </div>
  );
}

export default UserInputForm;

Context Hooks

Context allows a component to accept data from distant parents without having to send it as props.

Let’s build a basic theme-switching functionality that allows you to switch between bright and dark themes across various components.

ThemeContext.js

import React, { createContext, useContext, useState } from 'react';

const ThemeContext = createContext();

export function ThemeProvider({ children }) {
  const [isDarkTheme, setIsDarkTheme] = useState(false);

  const toggleTheme = () => {
    setIsDarkTheme((prevTheme) => !prevTheme);
  };

  return (
    <ThemeContext.Provider value={{ isDarkTheme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

export function useTheme() {
  return useContext(ThemeContext);
}

Ref Hooks

Refs allow a component to save data that isn’t utilized for rendering.

Ref Hooks are a mechanism to interact with and maintain references to DOM elements and other information that must persist between views in React. They are especially handy when you need to access or edit DOM components quickly, control attention, interface with third-party libraries, or work with mutable variables that should not cause re-renders.

Before introducing Ref Hooks, React relied heavily on the ref property and the React. React or createRef().To create and maintain references, use the Ref() methods.

Here’s a description of how and when to utilize Ref Hooks:

1.creating Refs

import React, { useRef } from 'react';

function MyComponent() {
  const myRef = useRef(null);

  // ...

  return <div ref={myRef}>Some content</div>;
}

2. Accessing and Modifying DOM Elements

import React, { useRef } from 'react';

function MyComponent() {
  const inputRef = useRef(null);

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <input ref={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}

3. Working with Mutable Values

import React, { useRef } from 'react';

function MyComponent() {
  const countRef = useRef(0);

  const incrementCount = () => {
    countRef.current += 1;
    console.log(countRef.current);
  };

  return (
    <div>
      <p>Count: {countRef.current}</p>
      <button onClick={incrementCount}>Increment</button>
    </div>
  );
}

Effect Hooks

Certainly! Effect Hooks are used in React for performing side effects in functional components. Data fetching, manual DOM modifications, subscriptions, and other effects are possible. For dealing with these side effects, React provides the useEffect hook.

Here’s a breakdown of how Effect Hooks operate and how to use them.

1. Importing ‘useEffect’

import React, { useEffect } from 'react';

2. Basic Usage

After the component has rendered, you may use useEffect to conduct actions. For example, when the component mounts, it can retrieve data from an API:

function MyComponent() {
  useEffect(() => {
    // Perform a side effect here, e.g., data fetching
    fetch('https://api.example.com/data')
      .then((response) => response.json())
      .then((data) => {
        // Update component state with fetched data
      });
  }, []); // The empty array [] means it runs only on component mount
}

3. Cleanup with ‘useEffect’

function MyComponent() {
  useEffect(() => {
    // Perform an effect

    return () => {
      // Perform cleanup when the component unmounts
    };
  }, [/*dependencies*/]);
}

4. Dependencies Arrays

function MyComponent(props) {
  useEffect(() => {
    // This effect runs on every render
    console.log('Effect ran');
  });

  useEffect(() => {
    // This effect runs only when 'props.someValue' changes
    console.log('Effect ran when someValue changed');
  }, [props.someValue]);
}

5. Multiple ‘useEffect’ Hooks

function MyComponent() {
  useEffect(() => {
    // One effect
  }, [/*dependencies1*/]);

  useEffect(() => {
    // Another effect
  }, [/*dependencies2*/]);
}

Performance Hooks

React Performance Hooks are a collection of hooks that aid in the optimization of React applications’ performance. They do this by memoizing values, which means they save the results of expensive operations and recompute them only when the dependencies change. This has the potential to dramatically enhance the performance of programs that conduct a large number of calculations or render enormous volumes of data.

useMemo and useCallback are the two most widely used Performance Hooks.

useMemo

The useMemo hook is used to memoize values. It accepts a function as the first parameter and an array of dependents as the second. If one of the dependents has changed since the previous time the function was called, the function will be invoked. The function’s return value will be memoized, which means it will be saved and reused until one of the dependents changes.

Here, you can see one of the example that showing usage of useMemo hook

const memoizedValue = useMemo(() => {
  // Expensive calculation
  return expensiveCalculation(someData);
}, [someData]);

The expensiveCalculation method will be run only if the someData dependence has changed in this example. Until the someData dependent changes, the memoizedValue will be saved and reused.

useCallback

The useCallback hook is used to memoize functions. It accepts a function as the first parameter and an array of dependents as the second. If one of the dependents has changed since the previous time the function was used, the function will be regenerated. The function that was memorized will be returned.

Example of the useCallback

const memoizedFunction = useCallback(() => {
  // Do something
}, [someData]);

The memoizedFunction will be rebuilt only if the someData dependence changes in this case. Until the someData dependent changes, the memoizedFunction will be reused.

Resource Hooks

React Resource Hooks are a set of hooks that allow you to access resources without their being part of the state of your component. A Promise, an asynchronous function, or a context object are examples of resources that can give data or functionality to your component.

The primary Resource Hook is the ‘use‘ hook. It accepts a resource as an input and returns the resource’s current value. The resource’s value will be updated anytime the resource changes.

You can see example below

const fetchData = async () => {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  return data;
};

const MyComponent = () => {
  const [data, setData] = useState(null);
  const promise = useMemo(() => fetchData(), []);
  const loadedData = use(promise);

  if (loadedData) {
    setData(loadedData);
  }

  return (
    <div>
      {data && <p>{data.message}</p>}
    </div>
  );
};

The use hook is used in this example to get the value of the promise resource. When the promise is resolved, the loadedData variable is updated. The setData method is then used to update the state of the component with the loaded data.

Leave a Comment