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.
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);
};
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.