Skip to content

React Hooks#

useState#

Manage component state.

const [state, setState] = useState(initialValue);

// Example
const [count, setCount] = useState(0);
const [user, setUser] = useState({ name: 'John', age: 30 });

// Update state
setCount(count + 1);
setCount(prev => prev + 1); // Using updater function

useEffect#

Side effects in components.

useEffect(() => {
  // Effect code

  return () => {
    // Cleanup (optional)
  };
}, [dependencies]);

// Examples
useEffect(() => {
  console.log('Runs on every render');
});

useEffect(() => {
  console.log('Runs once on mount');
}, []);

useEffect(() => {
  console.log('Runs when count changes');
}, [count]);

useRef#

Access DOM elements or persist values across renders.

const ref = useRef(initialValue);

// DOM access
function TextInput() {
  const inputRef = useRef<HTMLInputElement>(null);

  const focus = () => {
    inputRef.current?.focus();
  };

  return <input ref={inputRef} />;
}

// Persist value without re-render
const countRef = useRef(0);
countRef.current = countRef.current + 1;

useCallback#

Memoize functions.

const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);

// Example
const handleClick = useCallback(() => {
  console.log(count);
}, [count]);

useMemo#

Memoize expensive calculations.

const memoizedValue = useMemo(() => {
  return expensiveCalculation(a, b);
}, [a, b]);

// Example
const sortedList = useMemo(() => {
  return items.sort((a, b) => a.value - b.value);
}, [items]);

useContext#

Access context values.

const value = useContext(MyContext);

// Example
const ThemeContext = createContext('light');

function Button() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>Click me</button>;
}

useReducer#

Complex state logic.

const [state, dispatch] = useReducer(reducer, initialState);

// Example
type Action = 
  | { type: 'increment' }
  | { type: 'decrement' }
  | { type: 'set'; payload: number };

const reducer = (state: number, action: Action) => {
  switch (action.type) {
    case 'increment': return state + 1;
    case 'decrement': return state - 1;
    case 'set': return action.payload;
    default: return state;
  }
};

function Counter() {
  const [count, dispatch] = useReducer(reducer, 0);

  return (
    <>
      <p>{count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
    </>
  );
}

Custom Hooks#

function useLocalStorage<T>(key: string, initialValue: T) {
  const [value, setValue] = useState<T>(() => {
    const stored = localStorage.getItem(key);
    return stored ? JSON.parse(stored) : initialValue;
  });

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

  return [value, setValue] as const;
}

// Usage
function App() {
  const [name, setName] = useLocalStorage('name', 'John');
  return <input value={name} onChange={e => setName(e.target.value)} />;
}

Hook Rules

  • Only call hooks at the top level
  • Only call hooks from React functions
  • Custom hooks must start with "use"