Advanced Hooks in React: Beyond useState and useEffect

Advanced Hooks in React: Beyond useState and useEffect

Exploring advanced React hooks is key for developers looking to create efficient and scalable applications. This article dives into these hooks, offering insights and practical code examples.


React's Hooks API revolutionized functional components by providing a more intuitive way to handle state and side effects. Beyond the basics, advanced hooks offer nuanced control and optimization capabilities.


useReducer is ideal for complex state logic, offering a more structured approach than useState.


function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
      throw new Error();

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });
  return (
      Count: {state.count}
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>


useCallback is critical for preventing unnecessary re-renders, especially with memoized components.

Example and Pitfall:

const MyComponent = React.memo(({ onClick }) => {
  // Component implementation

function ParentComponent() {
  const [value, setValue] = useState('');

  // Incorrect use of useCallback can lead to unnecessary re-renders
  const handleClick = useCallback(() => {
    console.log('Value:', value);
  }, []); // Missing dependency: value

  return <MyComponent onClick={handleClick} />;

In this example, MyComponent will re-render whenever value changes because handleClick is not correctly memoized due to a missing dependency.


useMemo memoizes expensive calculations to optimize performance.


const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);


useRef is used for persisting values across renders and accessing DOM elements.


const inputEl = useRef(null);
const focusInput = () => inputEl.current && inputEl.current.focus();


useContext simplifies state management across components, making it easier to share data.


const value = useContext(MyContext);

// Example of a context provider
const MyContextProvider = ({ children }) => {
  const [value, setValue] = useState(initialValue);
  return <MyContext.Provider value={{ value, setValue }}>{children}</MyContext.Provider>;

Creating Custom Hooks

Custom hooks encapsulate logic and promote reusability.

Example: useFetch Hook:

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
      .then(response => response.json())
      .then(data => {
  }, [url]);

  return { data, loading };

(You can use any method instead of fetch.)


Mastering advanced hooks in React is crucial for creating efficient, clean, and maintainable applications.

Further Resources