React Native
setTimeout
JavaScript
Mobile Development
Asynchronous Programming

setTimeout in React Native

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

setTimeout works in React Native much like it does in browser JavaScript: it schedules a callback to run after a delay. The tricky part is not starting a timer, but cleaning it up correctly so components do not update state after unmount, and so timer behavior does not surprise you when the app moves between foreground and background.

Basic Timer Usage

The API is simple. Pass a callback and a delay in milliseconds, and setTimeout returns an identifier you can cancel.

javascript
1const timeoutId = setTimeout(() => {
2  console.log('ran later');
3}, 1000);
4
5clearTimeout(timeoutId);

That is enough for quick one-off delays. In component code, though, you almost never want to create timers at the top level of the render function.

The Right Pattern in Function Components

In React Native components, timers should usually be created inside useEffect and cleared in the cleanup function.

javascript
1import React, { useEffect, useState } from 'react';
2import { Text } from 'react-native';
3
4export default function DelayedMessage() {
5  const [message, setMessage] = useState('waiting...');
6
7  useEffect(() => {
8    const id = setTimeout(() => {
9      setMessage('done');
10    }, 2000);
11
12    return () => clearTimeout(id);
13  }, []);
14
15  return <Text>{message}</Text>;
16}

This pattern prevents a dangling timer from firing after the component has already been removed from the screen.

Stale Closures and Re-Renders

One subtle issue with timers is stale state. The callback captures values from the render that created it, so by the time the timeout fires, the state it reads may no longer be current.

If the latest value matters, either recreate the effect with the correct dependencies or store mutable data in a ref:

javascript
1import React, { useEffect, useRef } from 'react';
2
3function Example({ value }) {
4  const latestValue = useRef(value);
5
6  latestValue.current = value;
7
8  useEffect(() => {
9    const id = setTimeout(() => {
10      console.log(latestValue.current);
11    }, 1000);
12
13    return () => clearTimeout(id);
14  }, []);
15
16  return null;
17}

That is often safer than assuming the callback sees the newest props automatically.

App Lifecycle Matters

React Native timers are best-effort UI tools, not perfect schedulers. When the app is backgrounded, timers may pause, fire late, or behave differently depending on platform state and runtime conditions.

If the feature depends on lifecycle transitions, combine timer logic with AppState:

javascript
1import { AppState } from 'react-native';
2
3const subscription = AppState.addEventListener('change', (nextState) => {
4  console.log('app state:', nextState);
5});
6
7subscription.remove();

This matters for countdowns, inactivity tracking, temporary banners, and delayed navigation flows.

When setTimeout Is the Wrong Tool

Use setTimeout for short delays such as hiding a toast, waiting briefly before showing a loading hint, or deferring a small state update. Do not use it as a substitute for:

  • animation APIs
  • durable background scheduling
  • reliable polling infrastructure
  • complex debouncing logic across many renders

For animation, requestAnimationFrame or animation libraries are a better fit. For durable work that must survive app suspension, you need a different mechanism entirely.

Common Pitfalls

  • Starting a timeout in a component and forgetting to clear it on unmount.
  • Assuming timers fire at exact times even when the app is backgrounded or the device is busy.
  • Creating a new timeout on every render because the effect dependencies are wrong.
  • Updating state from a callback that captured stale props or state.
  • Using setTimeout for animation or durable scheduling problems it was never meant to solve.

Summary

  • 'setTimeout in React Native behaves like standard JavaScript, but cleanup is much more important in component code.'
  • Create timers inside effects and cancel them in the cleanup function.
  • Watch for stale closures when callbacks depend on changing state or props.
  • Treat timers as approximate UI delays, not precise schedulers.
  • Use lifecycle-aware or purpose-built tools when the problem is animation, debouncing, or background execution.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.