Mastering React Hooks: A Complete Guide
Back to Home
React

Mastering React Hooks: A Complete Guide

Ankit ChaubeyAnkit Chaubey
February 5, 2024
3 min read

Mastering React Hooks

React Hooks revolutionized how we write React components. Let's explore the most important hooks and advanced patterns.

useState: Managing State

The most basic hook for component state:

import { useState } from 'react';
 
function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

Advanced useState Patterns

Functional Updates:

// Use functional update when new state depends on previous
setCount(prevCount => prevCount + 1);

Lazy Initial State:

// Expensive computation only runs once
const [state, setState] = useState(() => {
  return expensiveComputation();
});

useEffect: Side Effects

Handle side effects in your components:

import { useEffect } from 'react';
 
function DataFetcher({ userId }) {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    fetch(`/api/user/${userId}`)
      .then(res => res.json())
      .then(setData);
  }, [userId]); // Re-run when userId changes
  
  return <div>{data?.name}</div>;
}

Cleanup Functions

useEffect(() => {
  const subscription = subscribeToData();
  
  // Cleanup function
  return () => {
    subscription.unsubscribe();
  };
}, []);

useContext: Global State

Share state without prop drilling:

import { createContext, useContext } from 'react';
 
const ThemeContext = createContext('light');
 
function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}
 
function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div className={theme}>Toolbar</div>;
}

useRef: Mutable References

Access DOM elements or store mutable values:

import { useRef } from 'react';
 
function TextInput() {
  const inputRef = useRef(null);
  
  const focusInput = () => {
    inputRef.current?.focus();
  };
  
  return (
    <>
      <input ref={inputRef} />
      <button onClick={focusInput}>Focus</button>
    </>
  );
}

useMemo: Performance Optimization

Memoize expensive computations:

import { useMemo } from 'react';
 
function ExpensiveComponent({ data }) {
  const processedData = useMemo(() => {
    return data.map(item => expensiveProcessing(item));
  }, [data]);
  
  return <List data={processedData} />;
}

useCallback: Memoize Functions

Prevent unnecessary re-renders:

import { useCallback } from 'react';
 
function Parent() {
  const [count, setCount] = useState(0);
  
  // Function reference stays the same
  const handleClick = useCallback(() => {
    setCount(c => c + 1);
  }, []);
  
  return <Child onClick={handleClick} />;
}

Custom Hooks

Create reusable logic:

function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    const stored = localStorage.getItem(key);
    return stored ? JSON.parse(stored) : initialValue;
  });
  
  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);
  
  return [value, setValue];
}
 
// Usage
function App() {
  const [name, setName] = useLocalStorage('name', '');
  
  return (
    <input
      value={name}
      onChange={e => setName(e.target.value)}
    />
  );
}

Advanced Patterns

useReducer for Complex State

import { useReducer } from 'react';
 
const reducer = (state, action) => {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      return state;
  }
};
 
function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });
  
  return (
    <>
      <p>{state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </>
  );
}

Rules of Hooks

  1. Only call at the top level - Don't call hooks inside loops, conditions, or nested functions
  2. Only call from React functions - Call from components or custom hooks

Conclusion

React Hooks provide a powerful way to manage state and side effects in your components. Master these patterns to write cleaner, more maintainable React code.

Next Steps:

  • Build custom hooks for common patterns
  • Explore the React documentation
  • Practice with real-world projects

Share this post

Ankit Chaubey

About Ankit Chaubey

Full-stack developer passionate about modern web technologies

Related Posts