React Custom Hooks
Custom hooks in React allow you to encapsulate reusable logic, making your components cleaner and more manageable. They are JavaScript functions that utilise built-in React hooks to provide specific functionality.
Why Use Custom Hooks?
- Promotes reusability by abstracting common logic.
- Keeps components focused on rendering rather than handling logic.
- Makes testing and debugging easier by isolating logic.
Syntax of a Custom Hook
</>
Copy
function useCustomHook(parameters) {
// Define state variables
// Implement logic using other hooks (e.g., useState, useEffect)
// Return the required data or functions
return { ...dataOrFunctions };
}
Description of the Syntax:
function useCustomHook(parameters)
: Custom hooks are regular JavaScript functions, but their names must start with “use” to follow React’s rules for hooks.- State Variables: You can use hooks like useState to manage internal state within the custom hook.
- Logic: The custom hook encapsulates reusable logic, often involving hooks like useEffect, useReducer, or useRef.
- Return Value: The hook typically returns an object or array containing the data and functions it provides to components.
Example 1: Fetch Data Hook
Custom hook to fetch data from an API.
useFetch.js
</>
Copy
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);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const json = await response.json();
setData(json);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
export default useFetch;
App.js
</>
Copy
import React from 'react';
import useFetch from './useFetch';
function App() {
const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/posts');
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<div>
<h1>Posts</h1>
<ul>
{data.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
export default App;
Explanation:
- The
useFetch
hook manages API calls and encapsulates loading, error, and data states. - It uses
useEffect
to call the API when the URL changes. - The
App
component uses the hook to display data, loading, or error states.
Output
Example 2: Window Size Hook
Custom hook to track the window size dynamically.
useWindowSize.js
</>
Copy
import { useState, useEffect } from 'react';
function useWindowSize() {
const [size, setSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
useEffect(() => {
const handleResize = () => {
setSize({
width: window.innerWidth,
height: window.innerHeight,
});
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return size;
}
export default useWindowSize;
App.js
</>
Copy
import React from 'react';
import useWindowSize from './useWindowSize';
function App() {
const { width, height } = useWindowSize();
return (
<div>
<h1>Window Size</h1>
<p>Width: {width}px</p>
<p>Height: {height}px</p>
</div>
);
}
export default App;
Explanation:
- The
useWindowSize
hook tracks window dimensions and updates them on resize. - It uses
useEffect
to attach and detach the resize event listener. - The
App
component uses this hook to display the current window dimensions.
Output
Conclusion
React Custom Hooks allow you to encapsulate logic and reuse it across components, improving code readability and maintainability.