Skip to content

useColorScheme() does not update after Appearance.setColorScheme() → requires two clicks to toggle theme #30

Description

@nandanNM

There is a consistent issue when implementing a manual light/dark theme toggle in React Native + Expo.

When calling:

Appearance.setColorScheme("light" | "dark");

the UI does not update on the first click.
It only updates after the second click.

This happens because useColorScheme() continues returning the old theme value for one extra render.

Observed Behavior

First click → theme changes internally
But useColorScheme() still returns previous value
→ UI does NOT switch theme

Second click → useColorScheme() finally updates
→ UI switches theme

This creates a broken two-click theme toggle experience.

Minimal Reproducible Example
import { useState } from "react";
import { Appearance, useColorScheme } from "react-native";

export function useModeToggle() {
const colorScheme = useColorScheme(); // ❗ stale value here
const [mode, setMode] = useState("light");

const toggleMode = () => {
const next = mode === "light" ? "dark" : "light";
setMode(next);

Appearance.setColorScheme(next); // ❗ does NOT notify useColorScheme() immediately

};

const isDark = colorScheme === "dark"; // ❗ updates 1 click late

return { isDark, toggleMode };
}

Expected Behavior

useColorScheme() should update immediately after calling:

Appearance.setColorScheme("dark");

so the theme changes after one click, not two.

Actual Behavior

Appearance.setColorScheme() applies correctly

but useColorScheme() updates on the next render, not immediately

causing the theme toggle to require two taps

This happens mostly on Android (Expo + React Native).

Request

Please confirm whether:

This is a known limitation

Expected behavior

Or a bug in Appearance → useColorScheme() event propagation

If this is a bug, please fix so that manual theme overrides trigger useColorScheme() updates immediately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions