CodeBlanks Logo Icon CodeBlanks

Summary - Theme

Combine Context, toggle and persistent theme to write a theme system.

Summary - Theme

The theme system has four parts: theme objects (light/dark), sharing with ThemeContext, system preference with useColorScheme, and persistence with AsyncStorage. The toggle switches between light and dark.

The Provider spreads the theme while useContext reads it; useEffect loads on launch and saves on change. These four form the theme infrastructure of real apps.

Practice Add ThemeContext and ThemeProvider

Add a ThemeContext and a ThemeProvider. The Provider holds const [theme, setTheme] = useState(light) and uses <ThemeContext.Provider value={theme}>. light is defined.

Starter code

App.js
import React, { createContext, useState } from 'react';
import { View } from 'react-native';

const light = { background: '#fff', text: '#000' };

// Add ThemeContext and ThemeProvider

export default function App() {
  return <View />;
}

Sample solution

App.js
import React, { createContext, useState } from 'react';
import { View } from 'react-native';

const light = { background: '#fff', text: '#000' };

const ThemeContext = createContext();

function ThemeProvider({ children }) {
  const [theme, setTheme] = useState(light);
  return (
    <ThemeContext.Provider value={theme}>
      {children}
    </ThemeContext.Provider>
  );
}

export default function App() {
  return (
    <ThemeProvider>
      <View />
    </ThemeProvider>
  );
}

Practice Add a toggle button

theme and setTheme are already taken with useContext(ThemeContext). Add a toggle button: const toggle = () => setTheme(theme === light ? dark : light) and <Button title="Switch" onPress={toggle} />. light and dark are defined.

Starter code

App.js
import React, { useContext } from 'react';
import { Button, Text, View } from 'react-native';

const light = { background: '#fff', text: '#000' };
const dark = { background: '#000', text: '#fff' };

const ThemeContext = React.createContext();

export default function App() {
  const { theme, setTheme } = useContext(ThemeContext);
  // Add a toggle button
  return (
    <View style={{ backgroundColor: theme.background }}>
      <Text style={{ color: theme.text }}>Theme</Text>
    </View>
  );
}

Sample solution

App.js
import React, { useContext } from 'react';
import { Button, Text, View } from 'react-native';

const light = { background: '#fff', text: '#000' };
const dark = { background: '#000', text: '#fff' };

const ThemeContext = React.createContext();

export default function App() {
  const { theme, setTheme } = useContext(ThemeContext);
  const toggle = () => setTheme(theme === light ? dark : light);
  return (
    <View style={{ backgroundColor: theme.background }}>
      <Text style={{ color: theme.text }}>Theme</Text>
      <Button title="Switch" onPress={toggle} />
    </View>
  );
}

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What is AsyncStorage used for?

  • Drawing a list
  • Generating colors
  • Storing the theme preference Correct answer
  • Navigation

Explanation: AsyncStorage stores the theme preference.

2 Theme summary

Term Meaning
ThemeContext Shares theme
useColorScheme System preference
AsyncStorage Persistent storage
toggle Light/dark switch

All lessons in Intermediate