Photo by Christopher Burns.

How to Detect User Color Preference in React Native

  • The Appearance API which lets you get their current color scheme
  • The useColorScheme hook which provides an up-to-date color scheme (it will automatically update as the user’s preferences change)
import React from "react"
import { View, Text, ViewStyle, TextStyle, StyleSheet } from "react-native"

const App = () => {
const viewStyles: ViewStyle[] = [
styles.container,
{ backgroundColor: "white" },
]
const textStyles: TextStyle[] = [styles.text, { color: "black" }]

return (
<View style={viewStyles}>
<Text style={textStyles}>Hello, world!</Text>
</View>
)
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
text: {
fontWeight: "bold",
fontSize: 20,
},
})

export default App
import React from "react"
import {
View,
Text,
ViewStyle,
TextStyle,
StyleSheet,
useColorScheme,
} from "react-native"

const App = () => {
const colorScheme = useColorScheme()
const isLightTheme = colorScheme === "light"

const viewStyles: ViewStyle[] = [
styles.container,
{ backgroundColor: isLightTheme ? "white" : "black" },
]
const textStyles: TextStyle[] = [
styles.text,
{ color: isLightTheme ? "black" : "white" },
]

return (
<View style={viewStyles}>
<Text style={textStyles}>Hello, world!</Text>
</View>
)
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
text: {
fontWeight: "bold",
fontSize: 20,
},
})

export default App

Improving Reusability with useColorScheme

import React from "react"
import {
View,
Text,
ViewStyle,
TextStyle,
StyleSheet,
useColorScheme,
} from "react-native"

const Colors = {
light: {
background: "white",
text: "black",
},
dark: {
background: "black",
text: "white",
},
}

const App = () => {
const colorScheme = useColorScheme()
const colors = Colors[colorScheme]

const viewStyles: ViewStyle[] = [
styles.container,
{ backgroundColor: colors.background },
]
const textStyles: TextStyle[] = [styles.text, { color: colors.text }]

return (
<View style={viewStyles}>
<Text style={textStyles}>Hello, world!</Text>
</View>
)
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
text: {
fontWeight: "bold",
fontSize: 20,
},
})

export default App

TypeScript Tip: Dealing with useColorScheme null Type

// hooks/ColorSchemeName.ts

import {
ColorSchemeName,
useColorScheme as _useColorScheme,
} from "react-native"

// The useColorScheme value is always either light or dark, but the built-in
// type suggests that it can be null. This will not happen in practice, so this
// makes it a bit easier to work with.
export default function useColorScheme(): NonNullable<ColorSchemeName> {
return _useColorScheme() as NonNullable<ColorSchemeName>
}

Custom useThemeColors Hook

// hooks/useThemeColors.ts
import useColorScheme from "hooks/useColorScheme"

const Colors = {
light: {
background: "white",
text: "black",
},
dark: {
background: "black",
text: "white",
},
}

const useThemeColors = () => {
const colorScheme = useColorScheme()
const colors = Colors[colorScheme]

return colors
}

export default useThemeColors
import React from "react"
import { View, Text, ViewStyle, TextStyle, StyleSheet } from "react-native"

import useThemeColors from "hooks/useThemeColors"

const App = () => {
const colors = useThemeColors()

const viewStyles: ViewStyle[] = [
styles.container,
{ backgroundColor: colors.background },
]
const textStyles: TextStyle[] = [styles.text, { color: colors.text }]

return (
<View style={viewStyles}>
<Text style={textStyles}>Hello, world!</Text>
</View>
)
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
text: {
fontWeight: "bold",
fontSize: 20,
},
})

export default App

Expanded Example

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store