useTheme
The useTheme hook lets us access the currently active theme. You can use it in your own components to have them respond to changes in the theme.
- Static
- Dynamic
import * as React from 'react';
import {
useNavigation,
createStaticNavigation,
DefaultTheme,
DarkTheme,
} from '@react-navigation/native';
import { View, Text, TouchableOpacity, useColorScheme } from 'react-native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { useTheme } from '@react-navigation/native';
// codeblock-focus-end
function SettingsScreen({ route }) {
const navigation = useNavigation();
const { user } = route.params;
const { colors } = useTheme();
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ color: colors.text }}>Settings Screen</Text>
<Text style={{ color: colors.text }}>
userParam: {JSON.stringify(user)}
</Text>
<Button onPress={() => navigation.navigate('Profile')}>
Go to Profile
</Button>
</View>
);
}
function ProfileScreen() {
const { colors } = useTheme();
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ color: colors.text }}>Profile Screen</Text>
</View>
);
}
// codeblock-focus-start
function MyButton() {
const { colors } = useTheme();
return (
<TouchableOpacity style={{ backgroundColor: colors.card }}>
<Text style={{ color: colors.text }}>Button!</Text>
</TouchableOpacity>
);
}
// codeblock-focus-end
function HomeScreen() {
const navigation = useNavigation();
const { colors } = useTheme();
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ color: colors.text }}>Home Screen</Text>
<MyButton />
<Button
onPress={() =>
navigation.navigate('Root', {
screen: 'Settings',
params: { user: 'jane' },
})
}
>
Go to Settings
</Button>
</View>
);
}
const PanelStack = createNativeStackNavigator({
screens: {
Profile: ProfileScreen,
Settings: SettingsScreen,
},
});
const Drawer = createDrawerNavigator({
initialRouteName: 'Panel',
screens: {
Home: HomeScreen,
Panel: {
screen: PanelStack,
options: {
headerShown: false,
},
},
},
});
const Navigation = createStaticNavigation(Drawer);
export default function App() {
const scheme = useColorScheme();
return <Navigation theme={scheme === 'dark' ? DarkTheme : DefaultTheme} />;
}
import * as React from 'react';
import { View, Text, TouchableOpacity, useColorScheme } from 'react-native';
import {
NavigationContainer,
DefaultTheme,
DarkTheme,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { useTheme } from '@react-navigation/native';
// codeblock-focus-end
function SettingsScreen({ route }) {
const navigation = useNavigation();
const { user } = route.params;
const { colors } = useTheme();
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ color: colors.text }}>Settings Screen</Text>
<Text style={{ color: colors.text }}>
userParam: {JSON.stringify(user)}
</Text>
<Button onPress={() => navigation.navigate('Profile')}>
Go to Profile
</Button>
</View>
);
}
function ProfileScreen() {
const { colors } = useTheme();
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ color: colors.text }}>Profile Screen</Text>
</View>
);
}
// codeblock-focus-start
function MyButton() {
const { colors } = useTheme();
return (
<TouchableOpacity style={{ backgroundColor: colors.card }}>
<Text style={{ color: colors.text }}>Button!</Text>
</TouchableOpacity>
);
}
// codeblock-focus-end
function HomeScreen() {
const navigation = useNavigation();
const { colors } = useTheme();
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ color: colors.text }}>Home Screen</Text>
<MyButton />
<Button
onPress={() =>
navigation.navigate('Root', {
screen: 'Settings',
params: { user: 'jane' },
})
}
>
Go to Settings
</Button>
</View>
);
}
const Drawer = createDrawerNavigator();
const Stack = createNativeStackNavigator();
function Root() {
return (
<Stack.Navigator>
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</Stack.Navigator>
);
}
export default function App() {
const scheme = useColorScheme();
return (
<NavigationContainer theme={scheme === 'dark' ? DarkTheme : DefaultTheme}>
<Drawer.Navigator>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen
name="Root"
component={Root}
options={{ headerShown: false }}
/>
</Drawer.Navigator>
</NavigationContainer>
);
}
See theming guide for more details and usage guide around how to configure themes.
Using with class component
You can wrap your class component in a function component to use the hook:
class MyButton extends React.Component {
render() {
// Get it from props
const { theme } = this.props;
}
}
// Wrap and export
export default function (props) {
const theme = useTheme();
return <MyButton {...props} theme={theme} />;
}