Custom hooks are functions that encapsulate reusable logic. When the complexity of a react application grows, managing the state and the logic that goes with it can become challenging. This is where custom hooks
come in.
They allow you to extract common patterns of stateful logic into reusable functions that can be shared across components. Custom hooks can be used to handle things like form validation, API calls, and more. In this blog, we'll explore the concept of custom hooks in ReactJS
and how they can be used to improve your code's reusability and maintainability.
Creating Custom Hooks
To create a custom hook in React, all you need to do is create a function that uses one or more built-in React hooks, such as useState or useEffect. Custom hooks can also call other custom hooks, enabling you to build complex, reusable logic that can be easily shared across components.
Here's an example of a custom hook that uses useState to manage a boolean value:
import { useState } from 'react';
export const useToggle = (initialState) => {
const [value, setValue] = useState(initialState);
const toggle = () => setValue(!value);
return [value, toggle];
};
In this example, the useToggle hook accepts an initial boolean value and returns an array containing the current boolean value and a function to toggle it. Any component that uses this hook can now easily manage a boolean state value by calling the useToggle function.
Using Custom Hooks
Using a custom hook in a component is as simple as calling the function and using the returned values. Here's an example of a component that uses the useToggle hook:
import { useToggle } from './useToggle';
const MyComponent = () => {
const [isToggledOn, toggle] = useToggle(false);
return (
<div>
<button onClick={toggle}>{isToggledOn ? 'ON' : 'OFF'}</button>
</div>
);
};
In the above example, the MyComponent
component imports the useToggle
hook and calls it to manage the state of a button's toggle switch. The hook's returned values are destructured into two variables: isToggledOn
and toggle
. The isToggledOn
variable contains the current boolean value, and the toggle function can be used to toggle it.
That was a very basic example. Now let's look into some real coding problem that you might face in one of your projects.
Real Coding Problem
Let's say you have to make an API
request to get a list of users and display this list on the client side. Normally what you would do (while using reactJS) is that, Make a component for it and in the useEffect
method of this component make this API
request and store data in the local state. Just like this:
function App() {
/* Conventional code to make an api request in a React Component */
const [data, setData] = useState();
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState('');
React.useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.json())
.then((json) => {
setData(json);
setTimeout(() => {
setIsLoading(false);
}, 1000);
})
.catch((error) => {
setError(error?.message);
});
});
return <div className='App'>{/* Show data in whatever way you like */}</div>;
}
export default App;
So what we are doing is that we are making an API
request inside the useEffect
hook and then we are setting the following state
variables:
-
data
: to store the data getting from theAPI
-
isLoading
: to check if data is loading -
error
: to store and show error message (if any)
However, if we need to make the same API
request elsewhere in our app, we would have to duplicate the above code. This approach is less than ideal, as we would not be able to reuse the same code. To address this issue, we can leverage custom hooks to achieve this. Let's see how this can be done.
Solution Using Custom Hooks
Now let's see how we will address the above problem using a custom hook. First we will create a custom hook named useUserApiRequest
:
export const useUserApiRequest = () => {
return [];
};
Then we will write the code where we will make the API
request inside the useEffect
hook and use the required state variables like this:
export const useUserApiRequest = () => {
const [data, setData] = useState();
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.json())
.then((json) => {
setData(json);
setTimeout(() => {
setIsLoading(false);
}, 1000);
})
.catch((error) => {
setError(error?.message);
});
});
return [data, isLoading, error];
};
Now we will see how we can use above custom hook
in our app. We will just call this hook like any other hook and it will return three variables that we were using previously to display information to the user.
function App() {
const [data, isLoading, error] = useUserApiRequest();
return <div className='App'>{/* Show data in whatever way you like */}</div>;
}
export default App;
If you look closely into the above code, there is no need to repeatedly duplicate the code when making an API request for user data rather we will use the one line where we are using the useUserApiRequest
hook get all the required. It's easy to write, understand and reusable at the same time and save us a lot of time.
Benefits of Custom Hooks
Using custom hooks in your React application can bring several benefits, including:
Reusability: Custom hooks enable you to extract common patterns of stateful logic into reusable functions that can be shared across components. This makes it easy to reuse the same logic in multiple components and reduces the amount of code you need to write.
Maintainability: By extracting logic into custom hooks, you can keep your component code clean and focused on the UI. This makes it easier to maintain and debug your code in the long run.
Testability: Custom hooks can be tested independently of your components, making it easier to write unit tests for your application's logic.
Conclusion
Custom hooks are a powerful tool for building reusable and maintainable logic in ReactJS. By extracting common patterns of stateful logic into reusable functions, you can reduce the amount of code you need to write and make it easier to maintain and test your application. Whether you're building a simple or complex React application, custom hooks are an essential tool to have in your toolbox.
Here is the Github repo link of the above used code.
Top comments (0)