React Hooks

Posted September 5, 2023 by Rohith and Anusha ‐ 3 min read

React, the JavaScript library for building user interfaces, has evolved significantly over the years. One of the most impactful changes introduced in React 16.8 was the concept of React Hooks. These Hooks have revolutionized how developers manage state and side-effects in functional components.

What Are React Hooks?

  • Before Hooks, React components mainly fell into two categories: class components and stateless functional components.

  • Class components could manage state and side-effects using lifecycle methods, while functional components were stateless and couldn’t manage their state.

  • React Hooks changed this paradigm by allowing functional components to manage state, side-effects, and other React features without the need for class components.

  • They are functions that let you hook into React state and lifecycle features from functional components.

Why Do React Hooks Matter?

React Hooks brought several advantages to the table:

Simplicity

  • Hooks simplify component logic by allowing you to reuse stateful logic across components without changing the component hierarchy.

  • This makes code more readable and maintainable.

Readability

  • Hooks encourage a more linear and readable code structure.

  • Instead of scattering related logic across lifecycle methods, everything is in one place.

No More Classes

  • If you prefer functional programming or simply find class components confusing, Hooks provide an elegant solution without the need for classes.

Easier Testing

  • Functional components using Hooks are easier to test because you can test each hook independently.

Commonly Used React Hooks

Let’s explore some of the most commonly used React Hooks:

useState

useState allows you to add state to your functional components. You provide an initial state value and receive the current state and a function to update it.

Here’s an example:

import React, { useState } from "react";

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

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

useEffect

useEffect is used for handling side-effects in your components, such as data fetching, DOM manipulation, or subscribing to external data sources. It takes a function as its first argument and an optional array of dependencies as the second argument.

Here’s an example:

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

function DataFetcher() {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch("https://api.example.com/data")
      .then((response) => response.json())
      .then((data) => setData(data));
  }, []);

  return <div>Data: {data}</div>;
}

useContext

useContext enables you to access the context values passed down from a higher-level component. This is useful for sharing global state or configuration settings.

Here’s an example:

import React, { useContext } from "react";

const ThemeContext = React.createContext("light");

function ThemedButton() {
  const theme = useContext(ThemeContext);

  return <button style={{ backgroundColor: theme }}>Themed Button</button>;
}

useRef

useRef allows you to create mutable references that persist across renders. It’s often used to interact with DOM elements or to store values that don’t trigger re-renders.

Here’s an example:

import React, { useRef } from "react";

function InputWithFocus() {
  const inputRef = useRef();

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

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

Building Custom Hooks

Apart from the built-in Hooks, you can also create your custom Hooks to encapsulate and reuse component logic. Custom Hooks follow a naming convention: they should start with use to signal that they are Hooks.

import { useState, useEffect } from "react";

function useDataFetching(url) {
  const [data, setData] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch(url)
      .then((response) => response.json())
      .then((data) => {
        setData(data);
        setIsLoading(false);
      })
      .catch((error) => {
        setError(error);
        setIsLoading(false);
      });
  }, [url]);

  return { data, isLoading, error };
}

Conclusion

  • React Hooks have transformed the way we write React components, making them more concise, readable, and maintainable.

  • With Hooks, you can handle state, side-effects, and context with ease, all while keeping your components as functional as possible.

  • As you continue your journey with React, embracing Hooks will undoubtedly be a game-changer in your development workflow.

quick-references blog react-hooks

Subscribe For More Content