What types of React hooks are there? What are their uses?
This article is based on the reference from this link.
What are the different types of hooks in React?
1. State Hooks
useState
This is the most commonly used React hook. It allows function components to have their own state variables.
It takes an initial value as an argument and returns an array with two values.
These values are the current state value and the function to update the state.
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); const increment = () => { setCount(count + 1); }; return ( <div> <p>Count: {count}</p> <button onClick={increment}>Increment</button> </div> ); }
useReducer
This hook provides an alternative to useState for handling complex state logic.
It’s useful when dealing with multiple sub-values or when the next state depends on the previous state’s value.
import React, { useReducer } from 'react'; const initialState = { count: 0 }; function reducer(state, action) { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; case 'reset': return initialState; default: throw new Error('Unsupported action type'); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); const increment = () => { dispatch({ type: 'increment' }); }; const decrement = () => { dispatch({ type: 'decrement' }); }; const reset = () => { dispatch({ type: 'reset' }); }; return ( <div> <p>Count: {state.count}</p> <button onClick={increment}>Increment</button> <button onClick={decrement}>Decrement</button> <button onClick={reset}>Reset</button> </div> ); }
2. Effect Hooks
useEffect
This hook is used for handling side effects such as data fetching, subscriptions, and DOM manipulations after a component renders.
import React, { useState, useEffect } from 'react'; function Example() { const [data, setData] = useState(null); useEffect(() => { // This effect runs after the component has rendered // Perform some asynchronous data fetching fetchData() .then((result) => { setData(result); }) .catch((error) => { console.error('Error fetching data:', error); }); // Clean up the effect return () => { // Perform any necessary cleanup here // This is optional but important to prevent memory leaks }; }, []); // Empty dependency array, so the effect runs only once on component mount return <div>{data ? <p>Data: {data}</p> : <p>Loading data...</p>}</div>; } export default Example;
useLayoutEffect
Similar to useEffect, but it runs synchronously after all DOM mutations have been applied, but before the browser paints.
It is useful for performing measurements or synchronously handling DOM changes.
import React, { useState, useLayoutEffect } from 'react'; function Example() { const [width, setWidth] = useState(0); useLayoutEffect(() => { // This effect runs synchronously after all DOM mutations // but before the browser paints const updateWidth = () => { const newWidth = document.documentElement.clientWidth; setWidth(newWidth); }; // Add event listener for window resize window.addEventListener('resize', updateWidth); // Initial width update updateWidth(); // Clean up the effect return () => { // Remove event listener window.removeEventListener('resize', updateWidth); }; }, []); // Empty dependency array, so the effect runs only once on component mount return <div>Window width: {width}px</div>; } export default Example;
useEffectOnce
This is a custom hook that ensures an effect runs only once when a component mounts.
import React, { useEffect } from 'react'; function useEffectOnce(effect) { // Do not include any dependency values in the array useEffect(effect, []); } // Usage: function Example() { useEffectOnce(() => { // This effect runs only once on component mount console.log('Effect ran only once'); }); return <div>Example Component</div>; } export default Example;
3. Context Hooks
useContext
This hook is used to consume values from React Context, allowing function components to access context values without prop drilling.
- Create a context
// createContext.js import React from 'react'; // Create a new context const MyContext = React.createContext(); export default MyContext;
- Provide a value using Context Provider
import React from 'react'; import MyContext from './createContext'; function App() { const value = 'Hello, Context!'; return ( <MyContext.Provider value={value}> <ChildComponent /> </MyContext.Provider> ); }
- Consume the context value using
useContext
import React, { useContext } from 'react'; import MyContext from './createContext'; function ChildComponent() { const contextValue = useContext(MyContext); return <div>{contextValue}</div>; }
4. Ref Hooks
useRef
This hook allows creating mutable references to values or DOM elements, and it persists across renders. It’s often used to access or manipulate DOM elements.
import React, { useRef } from 'react'; function Example() { const inputRef = useRef(null); const handleClick = () => { inputRef.current.focus(); }; return ( <div> <input type="text" ref={inputRef} /> <button onClick={handleClick}>Focus Input</button> </div> ); } export default Example;
5. Callback Hooks
useCallback
This hook memoizes a callback function. If the dependent values do not change, the callback won’t be recreated on each render, preventing unnecessary re-renders of child components and optimizing performance.
function Example() { const [count, setCount] = useState(0); const increment = useCallback(() => { setCount(count + 1); }, [count]); return ( <div> <p>Count: {count}</p> <button onClick={increment}>Increment</button> </div> ); } export default Example;
useMemo
This hook memoizes a value. It prevents re-calculating it on every render if its dependent values don’t change.
It is useful for optimizing expensive calculations or transforming complex data.
import React, { useState, useMemo } from 'react'; function Example() { const [count, setCount] = useState(0); const doubleCount = useMemo(() => { return count * 2; }, [count]); return ( <div> <p>Count: {count}</p> <p>Double Count: {doubleCount}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); } export default Example;
6. LayoutEffects
- useDimensions: Calculates the dimensions of an element.
- useWindowSize: Returns the current window size.
7. Form Hooks
- useForm: Provides form state and validation helpers.
8. Animation Hooks
- useSprings: Creates animated values for animation using React Spring.
9. Custom Hooks
- You can create your own custom hooks to encapsulate reusable logic and stateful behavior. Custom hooks should follow the naming convention of starting with “use” to ensure they can leverage other hooks.