Hooks in React

Hooks in React

Deep dive into useState, useEffect and useRef hooks

In the 16.8 version of React, Hooks are introduced to developers. When you are building a react application, you require manipulating with the states of your websites in majority cases. Before hooks, only class components could manage state.

If you have created a function component in React and later need to add state to it, you used to have to convert it to a class component. However, you can now use a Hook within the existing function component to add a state. This way, you can avoid rewriting your code as a class component.

With hooks, you can use state, manage side effects etc. This makes your code cleaner and more concise.

The most common hooks are useState for managing state, useEffect for managing side effects, and useRef for accessing and storing references to DOM elements or values that persist across renders without causing re-renders.

useState() Hook

useState allows you to manage state within functional components without the need for class-based components. It returns a stateful value and a function to update that value.

Example -

import React from 'react'
import { useState } from 'react';

const App = () => {

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

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  )
}

export default App

Output:

In this example, count is the state variable, initialized to 0 using useState(0). setCount is the function used to update the count state.

useEffect() Hook

useEffect hook allows us to perform side effects of the components. It runs after every render of the component and allows fetching data, directly updating the DOM and timers which are some side effects. It is called every time any state if the dependency array is modified or updated.

Here's a simple example -

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

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

  // useEffect is called after every render
  useEffect(() => {
    // Update the document title with the current count
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  )
}

export default App

Output:

In this example, useEffect is used to update the document title with the current count value whenever the count state changes. Initially, the title is set to "You clicked 0 times". When the button is clicked, the count state is updated, triggering a re-render, and then the useEffect hook runs again, updating the document title with the new count value. This demonstrates how useEffect allows you to perform side effects in functional components, in this case, updating the document title is dynamically based on component state.

The useEffect part of above example can also be written like this -

useEffect(() => {
    // Update the document title with the current count
    document.title = `You clicked ${count} times`;
 }, [count]); // Dependency array as second argument

You can optionally provide a dependency array as the second argument.

The effect will only run again if the count value of the dependency array changes.

Thus, it will provide the same output as before.

useRef() Hook

The useRef hook allows to directly create a reference to the DOM element in the functional component. Unlike useState if we change a value in useRef it will not re-render the webpage.

Since useRef hooks preserve value across various re-renders and do not cause re-renders whenever a value is changed they make the application faster and helps in storing previous values. The useRef returns a mutable ref object.

Here's a simple example:

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

const App = () => {

  const inputRef = useRef(null);

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

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

export default App

Output:

In this example, useRef is used to create a reference to the input element. When the button is clicked, the focusInput function is called, which focuses on the input element.