# How to Customize the React Native Status Bar Color for Different Screens

> Easily customize React Native status bar color for specific screens using the StatusBar component or imperative API. Learn how to dynamically change colors per screen for a better user experience.

- Repository: [Meta/react](https://github.com/facebook/react)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Use the `StatusBar` component from `react-native` or its imperative API (`setBackgroundColor`, `setBarStyle`) inside navigation focus effects to configure per-screen colors that apply only when a screen is active.**

Customizing the status bar color for individual screens requires controlling a native UI element that lives outside the React Native view hierarchy. While the core React library provides the reconciliation engine, the actual **StatusBar** implementation resides in the React Native repository. By leveraging the declarative `<StatusBar />` component or imperative static methods combined with navigation lifecycle hooks, you can dynamically adjust background colors and styles as users navigate between screens.

## Understanding the StatusBar API Architecture

The status bar is rendered by the operating system, not by React Native's JavaScript layer. React Native bridges JavaScript calls to native modules through the **StatusBar** component defined in [`Libraries/Components/StatusBar/StatusBar.js`](https://github.com/facebook/react/blob/main/Libraries/Components/StatusBar/StatusBar.js). This component exposes props like `backgroundColor` and `barStyle`, which map to native methods in [`NativeStatusBarManager.js`](https://github.com/facebook/react/blob/main/NativeStatusBarManager.js). For platform-specific logic, iOS handling resides in [`StatusBarIOS.js`](https://github.com/facebook/react/blob/main/StatusBarIOS.js) while Android background color and translucency controls live in [`StatusBarAndroid.js`](https://github.com/facebook/react/blob/main/StatusBarAndroid.js).

Because the status bar is global to the OS, its appearance must be set **each time a screen becomes active**. The typical pattern configures the status bar when the screen gains focus and optionally resets it when the screen loses focus.

## Method 1: Declarative StatusBar Component

Place a `<StatusBar />` component inside your screen's JSX to configure the status bar when the component mounts. React Native applies the props when the component mounts and updates them whenever the props change.

```tsx
import React from 'react';
import {View, Text, StatusBar} from 'react-native';

export default function HomeScreen() {
  return (
    <View style={{flex: 1, backgroundColor: '#4A90E2'}}>
      {/* The status bar adopts the background color and light text */}
      <StatusBar
        backgroundColor="#4A90E2"
        barStyle="light-content"
        animated={true}
      />
      <Text style={{color: 'white', fontSize: 24, marginTop: 40}}>
        Home Screen
      </Text>
    </View>
  );
}

```

The `animated` prop ensures smooth transitions. This approach works best when the status bar configuration should persist only while the component is mounted, as the component automatically cleans up on unmount.

## Method 2: Imperative API with Navigation Focus Effects

For precise control over when colors apply, especially when using React Navigation, use the imperative API inside `useFocusEffect`. This ensures the status bar changes only when the screen is actually visible to the user.

```tsx
import React from 'react';
import {View, Text, StatusBar} from 'react-native';
import {useFocusEffect} from '@react-navigation/native';

export default function DetailsScreen() {
  useFocusEffect(
    React.useCallback(() => {
      // Apply custom color when screen is active
      StatusBar.setBackgroundColor('#FF5722', true); // orange, animated
      StatusBar.setBarStyle('light-content', true);

      // Cleanup: revert to default when leaving
      return () => {
        StatusBar.setBackgroundColor('#FFFFFF', true); // default white
        StatusBar.setBarStyle('dark-content', true);
      };
    }, []),
  );

  return (
    <View style={{flex: 1, backgroundColor: '#FF5722'}}>
      <Text style={{color: 'white', fontSize: 24, marginTop: 40}}>
        Details Screen
      </Text>
    </View>
  );
}

```

The cleanup function prevents color bleeding during navigation, ensuring each screen maintains its intended appearance without affecting subsequent routes.

## Method 3: Custom Hook for Reusable Logic

Abstract the imperative calls into a custom hook to keep screen components clean and enforce consistent defaults across your application.

```tsx
// useStatusBar.ts
import {useEffect} from 'react';
import {StatusBar, StatusBarStyle} from 'react-native';

export function useStatusBar(
  backgroundColor: string,
  barStyle: StatusBarStyle = 'dark-content',
  animated = true,
) {
  useEffect(() => {
    StatusBar.setBackgroundColor(backgroundColor, animated);
    StatusBar.setBarStyle(barStyle, animated);
    
    return () => {
      // Optional: reset to app-wide defaults
      // StatusBar.setBackgroundColor('#FFF', animated);
      // StatusBar.setBarStyle('dark-content', animated);
    };
  }, [backgroundColor, barStyle, animated]);
}

```

```tsx
// In a screen component
import React from 'react';
import {View, Text} from 'react-native';
import {useStatusBar} from './useStatusBar';

export default function ProfileScreen() {
  useStatusBar('#8E44AD', 'light-content');

  return (
    <View style={{flex: 1, backgroundColor: '#8E44AD'}}>
      <Text style={{color: 'white', fontSize: 24, marginTop: 40}}>
        Profile
      </Text>
    </View>
  );
}

```

This approach centralizes status bar logic, making it easy to implement theme switching or global defaults while maintaining per-screen flexibility.

## React Native Source Implementation

While the current repository contains the core React reconciliation engine, the actual StatusBar implementation resides in the React Native repository. The component bridges JavaScript props to native OS calls through these key files:

- [`Libraries/Components/StatusBar/StatusBar.js`](https://github.com/facebook/react/blob/main/Libraries/Components/StatusBar/StatusBar.js) – Defines the React component and static imperative methods.
- [`Libraries/Components/StatusBar/NativeStatusBarManager.js`](https://github.com/facebook/react/blob/main/Libraries/Components/StatusBar/NativeStatusBarManager.js) – Native module interface that communicates with the OS.
- [`Libraries/Utilities/StatusBarIOS.js`](https://github.com/facebook/react/blob/main/Libraries/Utilities/StatusBarIOS.js) – iOS-specific style and visibility controls.
- [`Libraries/Utilities/StatusBarAndroid.js`](https://github.com/facebook/react/blob/main/Libraries/Utilities/StatusBarAndroid.js) – Android-specific background color and translucency handling.

Understanding this architecture explains why status bar changes must be triggered from JavaScript and why they require platform-specific considerations for background colors versus bar styles.

## Summary

- The **StatusBar** component and its static methods provide the only interface to customize the native status bar in React Native.
- Use **declarative** `<StatusBar />` components for simple, mount-based configuration that automatically cleans up on unmount.
- Use **imperative** API calls inside `useFocusEffect` or `useEffect` when you need precise control over when colors apply, especially with React Navigation.
- Always provide **cleanup logic** to reset status bar colors when leaving screens to prevent visual inconsistencies during navigation.
- The actual implementation lives in the React Native repository under `Libraries/Components/StatusBar/`, not in the core React library.

## Frequently Asked Questions

### How do I change the status bar color only on specific screens?

Place a `<StatusBar />` component with specific `backgroundColor` and `barStyle` props inside each screen component, or use the imperative `StatusBar.setBackgroundColor()` method inside `useFocusEffect` from React Navigation. This ensures the color change applies only when that screen is active and can be reset when navigating away.

### Why does my status bar color persist across screens?

The status bar is a global native UI element. If you don't provide cleanup logic in your `useEffect` or `useFocusEffect` return function, the color set on one screen remains when navigating to the next. Always reset the status bar to your app's default colors in the cleanup function, or use the declarative `<StatusBar />` component which automatically handles unmount cleanup.

### Can I animate status bar color transitions in React Native?

Yes. Pass `animated={true}` to the `<StatusBar />` component props, or pass `true` as the second argument to imperative methods like `StatusBar.setBackgroundColor(color, true)` and `StatusBar.setBarStyle(style, true)`. This triggers a native animation when the color or style changes.

### Does the StatusBar component work with Expo?

Yes. Expo uses the React Native `StatusBar` component under the hood. You can use the same declarative and imperative APIs in Expo projects. However, for managed Expo workflows, you might also configure default status bar behavior in [`app.json`](https://github.com/facebook/react/blob/main/app.json), but runtime changes per screen still use the React Native StatusBar API described above.