Skip to content

Custom hooks

Published: at 08:58 PM

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.


Previous Post
State management
Next Post
CSS layouts