React15 min read

React Hooks: A Complete Guide to useState and useEffect

Master the most commonly used React Hooks: useState and useEffect with practical examples.

David Park
December 3, 2025
22.4k891

React Hooks revolutionized how we write React components. They allow you to use state and other React features without writing class components.

useState Hook

The useState Hook lets you add state to functional components. It returns an array with two elements: the current state value and a function to update it.

useEffect Hook

The useEffect Hook lets you perform side effects in functional components. It serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount in class components.

Best Practices

When using Hooks, always follow the Rules of Hooks: only call Hooks at the top level and only call Hooks from React functions.

#React#Hooks#useState#useEffect

Common Questions & Answers

Q1

How does useState work internally?

A

useState uses React's internal state management system. When you call useState, React stores the state value in a queue associated with the component. On re-renders, it returns the current state value instead of the initial value.

javascript
// Basic useState
const [count, setCount] = useState(0);

// Functional update (when new state depends on previous)
const increment = () => {
  setCount(prevCount => prevCount + 1);
};

// Multiple state variables
const [name, setName] = useState('');
const [age, setAge] = useState(0);
const [isActive, setIsActive] = useState(false);

// Object state
const [user, setUser] = useState({
  name: '',
  email: '',
  age: 0
});

// Update object state (must spread previous state)
const updateUser = () => {
  setUser(prev => ({
    ...prev,
    name: 'John'
  }));
};
Q2

What is the dependency array in useEffect?

A

The dependency array is the second argument to useEffect. It tells React when to re-run the effect. If empty [], the effect runs once on mount. If it contains variables, the effect runs when those variables change. If omitted, it runs after every render.

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

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

// Runs after every render
useEffect(() => {
  console.log('Component rendered');
});

// Cleanup function
useEffect(() => {
  const timer = setInterval(() => {
    console.log('Tick');
  }, 1000);
  
  // Cleanup runs before next effect and on unmount
  return () => {
    clearInterval(timer);
  };
}, []);
Q3

When should you use useEffect vs useLayoutEffect?

A

Use useEffect for most side effects (data fetching, subscriptions, manual DOM changes). Use useLayoutEffect when you need to read layout from the DOM and synchronously re-render (measuring DOM nodes, preventing visual flashing). useLayoutEffect fires synchronously after DOM mutations but before the browser paints.