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.
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.