The React Hooks you need to know

Piyush NanwaniPiyush Nanwani
3 min read

In this blog, we'll cover fundamental hooks like useState, useEffect, useRef, and useContext. Then we will talk about custom hooks.

React Hooks

useState

The useState hook allows functional components to manage state. Let's look at a simple 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>
  );
}
  1. The code initializes a state variable named "count" using React's useState hook.

  2. The initial value of "count" is set to 0.

  3. The "setCount" function is a setter function provided by useState hook, used to update the value of "count" later in the component's lifecycle.

useEffect

useEffect enables performing side effects in functional components, such as fetching data or subscribing to external events. Here's an illustration:

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

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

  useEffect(() => {
    // Fetch data from an API
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []); // Empty dependency array triggers effect only once on mount

  return (
    <div>
      <ul>
        {data.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

useRef

useRef is handy for accessing and interacting with DOM elements directly. Consider the following example:

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

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

  useEffect(() => {
    // Focus the input element on mount
    inputRef.current.focus();
  }, []);

  return <input ref={inputRef} />;
}

useContext

The useContext hook simplifies accessing context values in functional components. Example:

import React, { useContext } from 'react';

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

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

  return <p style={{ color: theme }}>Themed Content</p>;
}

Custom Hooks

Custom hooks enable reusing stateful logic across different components. Let's create a simple custom hook for handling form input:

import { useState } from 'react';

function useFormInput(initialValue) {
  const [value, setValue] = useState(initialValue);

  const handleChange = e => {
    setValue(e.target.value);
  };

  return {
    value,
    onChange: handleChange,
  };
}

Now, you can use this custom hook in any component:

import React from 'react';
import useFormInput from './useFormInput';

function Form() {
  const username = useFormInput('');
  const password = useFormInput('');

  return (
    <form>
      <input type="text" {...username} placeholder="Username" />
      <input type="password" {...password} placeholder="Password" />
    </form>
  );
}

Another custom hook

Let's create a custom hook called useFetch for handling data fetching using the fetch API.

import { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(url);
        const result = await response.json();
        setData(result);
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [url]);

  return { data, loading, error };
}

// Usage example in a component
function DataComponent() {
  const { data, loading, error } = useFetch('https://api.example.com/data');

  if (loading) {
    return <p>Loading...</p>;
  }

  if (error) {
    return <p>Error: {error.message}</p>;
  }

  return (
    <div>
      <h1>Data Component</h1>
      <ul>
        {data.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

Now, you can reuse the useFetch hook in any component that needs to fetch data. This promotes code reusability and keeps your components focused on their specific concerns.

Thanks for reading!

1
Subscribe to my newsletter

Read articles from Piyush Nanwani directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Piyush Nanwani
Piyush Nanwani

Experienced full-stack developer with a passion for tackling complex challenges. Dedicated to helping you become a top 1% mobile app developer. Passionate about mentoring, teaching, and continuous learning in new technologies.