This post shows how custom hooks create cleaner code and benefits your project.
Table of contents
Open Table of contents
Benefits
Custom hooks are a great feature which seperates your code and allows you to use re-usable functions, they make your components look clean and prevent the developer having to copy and paste the same function. They are very similar to helper functions
but the only difference is they use hooks.
Examples
Counter
This first example will be able to display the count of the counter, then increment or decrement the count.
import { useState } from "react";
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(prev => prev + 1);
const decrement = () => setCount(prev => prev - 1);
const reset = () => setCount(initialValue);
return { count, increment, decrement, reset };
}
function CounterComponent() {
const { count, increment, decrement, reset } = useCounter(10);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+1</button>
<button onClick={decrement}>-1</button>
<button onClick={reset}>Reset</button>
</div>
);
}
export default CounterComponent;
Now this looks kindof messy, so what we can do is seperate the component from the logic which makes the component much cleaner and easier to read.
// app/customHooks.ts
export const useCounter = (initialValue = 0) => {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(prev => prev + 1);
const decrement = () => setCount(prev => prev - 1);
const reset = () => setCount(initialValue);
return { count, increment, decrement, reset };
};
import useCounter from "./customHooks.ts";
function CounterComponent() {
const { count, increment, decrement, reset } = useCounter(10);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+1</button>
<button onClick={decrement}>-1</button>
<button onClick={reset}>Reset</button>
</div>
);
}
Now if we want to use this hook in a different component all we need to do is import the useCounter
custom hook and it will work.
import useCounter from "./customHooks.ts";
const { count, increment, decrement, reset } = useCounter(10);
Boolean
This is a toggle which is used to change a boolean which shows / hides an element.
// app/customHooks.ts
import { useState } from "react";
export const useBoolean = (initialValue = false) => {
const [value, setValue] = useState(initialValue);
const toggle = () => setValue(prev => !prev);
const setTrue = () => setValue(true);
const setFalse = () => setValue(false);
return { value, toggle, setTrue, setFalse };
};
import useBoolean from "app/customHooks.ts";
function ToggleExample() {
const { value: isVisible, toggle } = useBoolean();
return (
<div>
<button onClick={toggle}>Toggle</button>
{isVisible && <p>Hello! I'm visible now.</p>}
</div>
);
}
Window size
This hook detects the users window size.
// app/customHooks.ts
import { useState, useEffect } from "react";
export const 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;
};
import useWindowSize from "./customHooks.ts";
function WindowSizeComponent() {
const { width, height } = useWindowSize();
return (
<p>
Width: {width}, Height: {height}
</p>
);
}
Conclusion
Custom hooks are very powerful when you need to re-use logic in multiple components that depend on hooks, they allow developers to encapsulate and share stateful logic in a clear way - this also helps with reduced complexity and makes it easier for collaboration.