5 Unpopular Hooks You Need to Know in REACTJS

Do you want to optimize your code and take your development skills to the next level? Look no further! In this article, we'll explore five unpopular React hooks that you may not know about, but can greatly benefit from.

Use Imperative Handle

The first hook we'll cover is use Imperative Handle. This hook allows you to customize the behavior of a component when it is accessed by a parent component using a ref. Think of it like reprogramming a toy robot's remote control to perform custom actions. In a parent-child component relationship, use Imperative Handle enables you to control the child component's actions without passing functions as props. Below is the code sample on how to use this hooks:

import React, { useState, useRef, forwardRef, useImperativeHandle } from 'react';

const CountdownTimer = forwardRef((props, ref) => {
  const [time, setTime] = useState(props.initialTime);
  const intervalRef = useRef(null);

  const startTimer = () => {
    if (!intervalRef.current) {
      intervalRef.current = setInterval(() => {
        setTime((prevTime) => {
          if (prevTime === 0) {
            clearInterval(intervalRef.current);
            return 0;
          }
          return prevTime - 1;
        });
      }, 1000);
    }
  };

  const stopTimer = () => {
    clearInterval(intervalRef.current);
    intervalRef.current = null;
  };

  const resetTimer = () => {
    setTime(props.initialTime);
  };

  // Expose custom methods via useImperativeHandle
  useImperativeHandle(ref, () => ({
    start: startTimer,
    stop: stopTimer,
    reset: resetTimer,
  }));

  const timerStyle = {
    fontSize: '48px', // Set font size
    fontWeight: 'bold', // Make text bold
    color: '#333', // Set text color
    padding: '10px', // Add some padding
    border: '2px solid #333', // Add border
    borderRadius: '5px', // Add border radius for rounded corners
    width: '100px', // Set width
    textAlign: 'center', // Center text horizontally
  };

  return <div style={timerStyle}>{time}</div>; // Apply inline style
});

function App() {
  const timerRef = useRef();

  const handleStart = () => {
    timerRef.current.start();
  };

  const handleStop = () => {
    timerRef.current.stop();
  };

  const handleReset = () => {
    timerRef.current.reset();
  };

  return (
    <div>
      <CountdownTimer ref={timerRef} initialTime={10} />
      <button onClick={handleStart}>Start</button>
      <button onClick={handleStop}>Stop</button>
      <button onClick={handleReset}>Reset</button>
    </div>
  );
}

export default App;

Use Layout Effect

The second hook we'll cover is use Layout Effect. This hook is similar to use Effect, but it's specific to layout-related effects. It's useful when you want to perform some action after all DOM mutations, such as measuring the layout of a component. Below is the code sample on how to use this hooks:

import React, { useLayoutEffect, useRef, useState } from 'react';

export function App() {
  const [height, setHeight] = useState(0);
  const divRef = useRef();

  useLayoutEffect(() => {
    setHeight(divRef.current.getBoundingClientRect().height);
  }, []);

  return (
    <div style={{color:'white'}}>
      <div ref={divRef} style={{ height: '100px', background: 'lightblue' }}>
        Measure my height
      </div>
      <p>The height of the above div is: {height}px</p>
    </div>
  );
}

Use Defer Value

The third hook we'll cover is use Defer Value. This hook helps manage state changes in a way that keeps your app responsive, especially during complex updates. Think of it like typing a search query and waiting for the results to load before making another API request. This hook is especially useful when you want to optimize your app's performance by delaying API requests until the user has finished typing. Below is the code sample on how to use this hooks:

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

const SearchBar = () => {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query, { timeoutMs: 500 }); // Delay updating the query value

  // Simulate an API request based on the search query
  useEffect(() => {
    const fetchData = async () => {
      if (deferredQuery !== '') {
        // Send API request with the deferred query
        console.log(`Sending API request for: ${deferredQuery}`);
        // Here you can fetch data from your API based on the deferredQuery
        // For demonstration purposes, I'm just logging the query to the console
      }
    };

    // Wait for a short delay before sending the API request
    const timeoutId = setTimeout(fetchData, 500);

    // Cleanup the timeout if the user types again before the timeout completes
    return () => clearTimeout(timeoutId);
  }, [deferredQuery]);

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

  return (
    <div>
      <input type="text" value={query} onChange={handleChange} placeholder="Search..." />
    </div>
  );
};

export function App(){
  return (
    <div style={{color:'white'}}>
      <h1>Type-ahead Search Example</h1>
      <SearchBar />
    </div>
  );
};

useTransition

The fourth hook we'll cover is useTransition. This hook helps manage state changes in a way that keeps your app responsive, especially during complex updates. Think of it like loading a new level in a video game while the user continues to play. Use Transition ensures that your app remains responsive while changes are being made in the background. This hook is especially useful when you want to make changes to your app without disturbing the user's current actions. Below is the code sample on how to use this hooks:

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

const Form = () => {
  const [formData, setFormData] = useState({ name: '', email: '' });
  const [isSubmitting, startTransition] = useTransition();

  const handleSubmit = async (e) => {
    e.preventDefault();
    startTransition(() => {
      // Simulate a delay for form submission
      setTimeout(async () => {
        try {
          // Here you can make an API request to submit the form data
          console.log('Form submitted:', formData);
          // Simulate a success message after submission
          alert('Form submitted successfully!');
          // Clear the form data after successful submission
          setFormData({ name: '', email: '' });
        } catch (error) {
          // Handle error
          console.error('Form submission error:', error);
          alert('An error occurred while submitting the form. Please try again.');
        }
      }, 2000); // Simulate a 2-second delay for submission
    });
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData((prevFormData) => ({
      ...prevFormData,
      [name]: value,
    }));
  };

  return (
    <div>
      <h2>Form Submission Example</h2>
      <form onSubmit={handleSubmit}>
        <label>
          Name:
          <input type="text" name="name" value={formData.name} onChange={handleChange} />
        </label>
        <br />
        <label>
          Email:
          <input type="email" name="email" value={formData.email} onChange={handleChange} />
        </label>
        <br />
        <button type="submit" disabled={isSubmitting}>
          {isSubmitting ? 'Submitting...' : 'Submit'}
        </button>
      </form>
    </div>
  );
};

export function App(){
  return (
    <div style={{color:'white'}}>
      <h1>React Form Submission Example</h1>
      <Form />
    </div>
  );
};

Use ID

The fifth and final hook we'll cover is use ID. This hook generates unique IDs for elements, ensuring consistency and uniqueness, which is important for accessibility and form handling. Think of it like giving each element in your app a unique badge. It generates a unique ID that you can use for your form elements. This hook is especially useful when you want to generate unique IDs for your form elements without having to rack your brain for unique names.

import React, { useId } from 'react';

export function App() {
  const id = useId();


  return (
    <div style={{color:'white'}}>
      <label htmlFor={id}>Username: </label>
      <input id={id} type="text" />
    </div>
  );
}

Conclusion

In conclusion, these five unpopular React hooks can greatly benefit your projects by optimizing your code, improving performance, and enhancing user experience. By using use Imperative Handle, use Layout Effect, use Defer Value, use Transition, and use ID, you can take your development skills to the next level and build faster, more responsive, and more accessible apps.

0
Subscribe to my newsletter

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

Written by

Oluwajuwon Falore
Oluwajuwon Falore

I am a full-Stack (backend leaning) software developer. Experienced with all stages of the development cycle for dynamic web projects. Well-versed in programming languages including HTML5, CSS, JAVASCRIPT, NODEJS, GOLANG, REACTJS, PYTHON, ANGULAR and IONIC.