The useEffect hook in React lets you perform side effects in function components, such as data fetching, DOM updates, timers, and subscriptions. It runs after the component renders, keeping your UI in sync with external systems.
With useEffect, you can control when side effects run using a dependency array, making your code efficient and easy to manage. This hook replaced lifecycle methods like componentDidMount and componentDidUpdate in class components, simplifying how React apps handle effects.
Understanding useEffect Hook
- Runs after render, handling side effects like data fetching, subscriptions, or DOM updates.
- Dependent on a dependency array that tells React when to rerun the effect.
- Cleanup function option to remove subscriptions or timers on unmount.
Example:
Comparing useEffect with useLayoutEffect
- useEffect runs after browser paint, great for non-blocking effects (like fetching data).
- useLayoutEffect runs before browser paint, useful when you need to measure or mutate the DOM to prevent flickering or layout shifts.
Example:
useEffect Hook Used in Different Scenarios
1- Fetching Data on Component Mount
2- Running Side Effects When Props or State Change
3- Event Listener Setup and Cleanup
4- Timer or Interval Setup
5- Cleaning up Subscriptions or External APIs
6- Multiple Effects for Separation of Concerns
7- Running an Effect on Every Render
Best Practices for useEffect
- Specify dependencies correctly: Always provide a dependency array to control when the effect runs and avoid infinite loops.
- Use cleanup functions: Prevent memory leaks by cleaning up subscriptions, timers, or event listeners.
- Split concerns: Use multiple useEffect hooks to separate unrelated side effects.
- Avoid heavy logic inside effects: Keep the effect function focused on side effects; handle calculations outside if possible.
- Do not update state unconditionally inside effects: To avoid infinite renders, update state conditionally or using the dependency array.
- Be mindful of stale closures: Use refs or adjust dependencies to ensure your effect has access to the latest state or props.
Developer Tips
- Always declare hooks at the top level.
- Use dependency arrays thoughtfully for performance.
- Prefer useEffect over useLayoutEffect unless layout measurement is required.
- Extract common logic with custom hooks.
Conclusion
useEffect is a powerful and versatile hook that helps manage side effects cleanly within functional components. By understanding how to use dependency arrays and cleanup functions, you can avoid common pitfalls like infinite loops or memory leaks.
Whether setting timers, fetching data, or managing event listeners, useEffect gives you fine control over when and how side effects occur. Mastering this hook is essential for writing effective, modern React components.