Top 10 Most Useful Custom Hooks in React

deepak chandra
3 min readMar 26, 2024

--

Custom hooks in React are reusable functions that contain logic shared across multiple components. They enable developers to extract complex logic from components and encapsulate it into reusable units. Here are ten custom hooks commonly found useful in React development:

### 1. `useFetch`:

**Purpose:** Perform HTTP requests and manage loading, error, and data states.

**Example:**

const 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);
const result = await response.json();
setData(result);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};

fetchData();
}, [url]);

return { data, loading, error };
};

### 2. `useLocalStorage`:

**Purpose:** Synchronize state with local storage, maintaining state persistence.

**Example:**

const useLocalStorage = (key, initialValue) => {
const [value, setValue] = useState(() => {
const storedValue = localStorage.getItem(key);
return storedValue !== null ? JSON.parse(storedValue) : initialValue;
});

useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);

return [value, setValue];
};

### 3. `useDebounce`:

**Purpose:** Debounce expensive operations such as search or API requests to improve performance.

**Example:**

const useDebounce = (value, delay) => {
const [debouncedValue, setDebouncedValue] = useState(value);

useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);

return () => {
clearTimeout(handler);
};
}, [value, delay]);

return debouncedValue;
};

### 4. `useMediaQuery`:

**Purpose:** Detect changes in viewport size or device orientation.

**Example:**

const useMediaQuery = (query) => {
const [matches, setMatches] = useState(false);

useEffect(() => {
const mediaQuery = window.matchMedia(query);
setMatches(mediaQuery.matches);

const handleMediaChange = (event) => {
setMatches(event.matches);
};

mediaQuery.addEventListener('change', handleMediaChange);
return () => {
mediaQuery.removeEventListener('change', handleMediaChange);
};
}, [query]);

return matches;
};

### 5. `useKeyPress`:

**Purpose:** Detect keyboard key presses.

  • *Example:**
const useKeyPress = (targetKey) => {
const [keyPressed, setKeyPressed] = useState(false);

const downHandler = ({ key }) => {
if (key === targetKey) {
setKeyPressed(true);
}
};

const upHandler = ({ key }) => {
if (key === targetKey) {
setKeyPressed(false);
}
};

useEffect(() => {
window.addEventListener('keydown', downHandler);
window.addEventListener('keyup', upHandler);
return () => {
window.removeEventListener('keydown', downHandler);
window.removeEventListener('keyup', upHandler);
};
}, [targetKey]);

return keyPressed;
};

### 6. `useScrollPosition`:

**Purpose:** Track the current scroll position of an element.

**Example:**

const useScrollPosition = () => {
const [scrollPosition, setScrollPosition] = useState(0);

useEffect(() => {
const handleScroll = () => {
setScrollPosition(window.scrollY);
};

window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);

return scrollPosition;
};

### 7. `useToggle`:

**Purpose:** Toggle between two states.

**Example:**

const useToggle = (initialValue = false) => {
const [value, setValue] = useState(initialValue);

const toggle = () => {
setValue((prevValue) => !prevValue);
};

return [value, toggle];
};

### 8. `usePrevious`:

**Purpose:** Access the previous value of a state or prop.

**Example:**

const usePrevious = (value) => {
const ref = useRef();

useEffect(() => {
ref.current = value;
}, [value]);

return ref.current;
};

### 9. `useAnimationFrame`:

**Purpose:** Perform animations using the browser’s requestAnimationFrame API.

**Example:**

const useAnimationFrame = (callback) => {
const requestRef = useRef();

const animate = (time) => {
callback(time);
requestRef.current = requestAnimationFrame(animate);
};

useEffect(() => {
requestRef.current = requestAnimationFrame(animate);
return () => cancelAnimationFrame(requestRef.current);
}, [animate]);
};

### 10. `useEventListener`:

**Purpose:** Attach event listeners to elements.

**Example:**

const useEventListener = (eventName, handler, element = window) => {
useEffect(() => {
if (!(element && element.addEventListener)) {
return;
}

element.addEventListener(eventName, handler);

return () => {
element.removeEventListener(eventName, handler);
};
}, [eventName, handler, element]);
};

These custom hooks can significantly enhance code reusability, readability, and maintainability in React applications by encapsulating common logic into reusable functions.

--

--

deepak chandra
deepak chandra

Written by deepak chandra

I am a developer and designer from India🇮🇳. I have a passion for programming and designing. I'd call myself a Jack of all trades but master of none.

No responses yet