Expo Playground

useEffect Hook

useEffect tells your component to do something after it appears on screen — like loading data from the internet, starting a timer, or listening for updates. When React mounts your component (first appears on screen), that's when effects start running.

useEffect(() => {
  fetchUserProfile();
}, []);

The dependency array

The second argument controls when the effect runs:

// Runs ONCE after first render (mount)
useEffect(() => {
  loadData();
}, []);

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

// Runs after EVERY render (usually a mistake)
useEffect(() => {
  // Be careful with this!
});

Cleanup functions

Return a function to clean up when the component unmounts (removed from screen) or before re-running:

useEffect(() => {
  const timer = setInterval(() => tick(), 1000);

  // Cleanup: stop the timer
  return () => clearInterval(timer);
}, []);

This prevents memory leaks (keeps doing work for a component that's gone) — a common source of bugs in mobile apps.

Common patterns in Expo

// Fetch data on mount
useEffect(() => {
  async function load() {
    const response = await fetch(API_URL);
    const data = await response.json();
    setItems(data);
  }
  load();
}, []);

Try this: Add a useEffect that logs "Component mounted!" when the screen loads, and "Goodbye!" when it unmounts.

See this concept in action with interactive code highlighting

Try in Playground