CodeMasteryLab
Section 5

React Hooks Deep Dive

Master all React hooks and create custom hooks

React Hooks Deep Dive

useContext Hook

Share data 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>Current theme: {theme}</div>;
}

useReducer Hook

Manage complex state logic:

import { useReducer } from 'react';

function 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 (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </div>
  );
}

useRef Hook

Access DOM elements or persist values:

import { useRef } from 'react';

function TextInput() {
  const inputRef = useRef(null);

  function focusInput() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </>
  );
}

useMemo and useCallback

Optimize performance with memoization:

import { useMemo, useCallback } from 'react';

function ExpensiveComponent({ data }) {
  // Only recalculate when data changes
  const processedData = useMemo(() => {
    return data.map(item => item * 2);
  }, [data]);

  // Memoize callback function
  const handleClick = useCallback(() => {
    console.log(data);
  }, [data]);

  return <div>{/* Use processedData */}</div>;
}

Custom Hooks

Create reusable logic:

function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    const item = localStorage.getItem(key);
    return item ? JSON.parse(item) : 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)} />;
}