---
title: Bitovi Academy - Managing State with useState
description: Work with React’s useState Hook to manage a component’s state.
---

- ![AI implementation](https://www.bitovi.com/hubfs/AIConsultingIcon.svg)
  
  [AI implementation](https://www.bitovi.com/services/ai-consulting?hsLang=en-us)
- ![Systems engineering](https://www.bitovi.com/hubfs/icon%20-%20backend.svg)
  
  [Systems engineering](https://www.bitovi.com/services/systems-engineering-consulting?hsLang=en-us)
- ![Project management](https://www.bitovi.com/hubfs/icon%20-%20PM.svg)
  
  [Project management](https://www.bitovi.com/services/agile-project-management-consulting?hsLang=en-us)
- ![Product design](https://www.bitovi.com/hubfs/icon%20-%20design.svg)
  
  [Product design](https://www.bitovi.com/services/product-design-consulting?hsLang=en-us)
- ![Frontend development](https://www.bitovi.com/hubfs/icon%20-%20frontend.svg)
  
  [Frontend development](https://www.bitovi.com/services/frontend-development-consulting?hsLang=en-us)
- [View more
  
  →
  
  ](https://www.bitovi.com/digital-consulting-services?hsLang=en-us)

We're Experts in...

- [JavaScript](https://www.bitovi.com/services/frontend/javascript-consulting?hsLang=en-us)
- [AI training](https://www.bitovi.com/ai-training-for-software-engineers?hsLang=en-us)
- [Angular](https://www.bitovi.com/services/frontend/angular-consulting?hsLang=en-us)
- [Design Systems](https://www.bitovi.com/services/axure-figma-migration?hsLang=en-us)
- [React](https://www.bitovi.com/services/frontend/react-consulting?hsLang=en-us)
- [Temporal](https://www.bitovi.com/services/backend/temporal-consulting?hsLang=en-us)
- [React Native](https://www.bitovi.com/services/frontend/react-consulting/react-native?hsLang=en-us)
- [Node.js](https://www.bitovi.com/services/backend/nodejs-consulting-1?hsLang=en-us)

Showcase

![Yum! Brands](https://www.bitovi.com/hubfs/yum-showcase-link-1.png)

[View case study](https://www.bitovi.com/en/bitovi-yum-case-study?hsLang=en-us)

More Projects

- [![Levi's](https://www.bitovi.com/hubfs/levis.svg)](https://www.bitovi.com/web-application-consulting-work/levis-ecommerce-responsive-redesign?hsLang=en-us)
- [![Christie's International Real Estate](https://www.bitovi.com/hubfs/christies.svg)](https://design.bitovi.com/christies)
- [![BAFS](https://www.bitovi.com/hubfs/bafs.svg)](https://www.bitovi.com/ux-design-consulting/ux-case-studies/bafs-ppp?hsLang=en-us)
- [View more
  
  →
  
  ](https://www.bitovi.com/our-software-consulting-work?hsLang=en-us)

Open Source Tools

We build powerful tools and open source them to support the community.

[See what we've built →](https://www.bitovi.com/open-source?hsLang=en-us)

- [![Blog](https://www.bitovi.com/hubfs/icon%20-%20blog.svg)
  
  BlogWe post about perfecting software delivery
  
  ](https://bitovi.com/blog)
- [![Partnerships](https://www.bitovi.com/hubfs/Handshake-1.svg)
  
  PartnershipsLearn about Bitovi's technology partners
  
  ](https://www.bitovi.com/partnerships?hsLang=en-us)
- [![Academy](https://www.bitovi.com/hubfs/limbo/icons/icon-academy.svg)
  
  AcademyFree courses to build delivery skills
  
  ](https://www.bitovi.com/academy/?hsLang=en-us)
- [![Open source tools](https://www.bitovi.com/hubfs/icon%20-%20open%20source.svg)
  
  Open source toolsUse our tools or contribute to our open source mission.
  
  ](https://www.bitovi.com/open-source?hsLang=en-us)

Let's Connect

- [![Discord](https://www.bitovi.com/hubfs/DiscordLogo.svg)
  
  Discord
  
  ](https://discord.gg/J7ejFsZnJ4)
- [![LinkedIn](https://www.bitovi.com/hubfs/LinkedinLogo.svg)
  
  LinkedIn
  
  ](https://www.linkedin.com/company/bitovi/)
- [![GitHub](https://www.bitovi.com/hubfs/GithubLogo.svg)
  
  GitHub
  
  ](https://github.com/bitovi/)

![Eggbot](https://www.bitovi.com/hubfs/build_assets/bitovi-limbo-cms-react/338/js_client_assets/assets/eggbot-LTGhdSGL.png)

Name *

Work Email *

Phone

What's your project?

Send

### Contact Us

(312) 620-0386contact@bitovi.com

- [ Advanced JavaScript ](https://www.bitovi.com/academy/learn-advanced-javascript.html?hsLang=en-us)
- [ DOM and jQuery ](https://www.bitovi.com/academy/learn-dom-jquery.html?hsLang=en-us)
- [ Debug JavaScript ](https://www.bitovi.com/academy/learn-to-debug-javascript.html?hsLang=en-us)
- [ Learn TypeScript ](https://www.bitovi.com/academy/learn-typescript.html?hsLang=en-us)
- [ Learn React Native ](https://www.bitovi.com/academy/learn-react-native.html?hsLang=en-us) 
    - [ Introduction to React Native ](https://www.bitovi.com/academy/learn-react-native/intro-to-react-native.html?hsLang=en-us)
    - [ Setting Up Your Environment ](https://www.bitovi.com/academy/learn-react-native/setting-up-your-environment.html?hsLang=en-us)
    - [ Creating a New Application ](https://www.bitovi.com/academy/learn-react-native/creating-a-new-app.html?hsLang=en-us)
    - [ Introduction to JSX ](https://www.bitovi.com/academy/learn-react-native/intro-to-jsx.html?hsLang=en-us)
    - [ Introduction to Testing ](https://www.bitovi.com/academy/learn-react-native/intro-to-testing.html?hsLang=en-us)
    - [ Building Custom Components ](https://www.bitovi.com/academy/learn-react-native/building-custom-components.html?hsLang=en-us)
    - [ Debugging and DevTools ](https://www.bitovi.com/academy/learn-react-native/debugging-devtools.html?hsLang=en-us)
    - [ Styling in React Native ](https://www.bitovi.com/academy/learn-react-native/styling.html?hsLang=en-us)
    - [ Using React Context ](https://www.bitovi.com/academy/learn-react-native/react-context.html?hsLang=en-us)
    - [ Managing State with useState ](https://www.bitovi.com/academy/learn-react-native/managing-state.html?hsLang=en-us)
    - [ Navigation in React Native ](https://www.bitovi.com/academy/learn-react-native/navigation.html?hsLang=en-us)
    - [ Storing State in Navigation Parameters ](https://www.bitovi.com/academy/learn-react-native/navigation-params.html?hsLang=en-us)
    - [ Making HTTP Requests ](https://www.bitovi.com/academy/learn-react-native/making-http-requests.html?hsLang=en-us)
    - [ Handling User Inputs ](https://www.bitovi.com/academy/learn-react-native/user-inputs.html?hsLang=en-us)
    - [ Using Async Storage ](https://www.bitovi.com/academy/learn-react-native/using-asyncstorage.html?hsLang=en-us)
    - [ Security and Authentication ](https://www.bitovi.com/academy/learn-react-native/security-and-auth.html?hsLang=en-us)
    - [ Adding Offline Support ](https://www.bitovi.com/academy/learn-react-native/offline-support.html?hsLang=en-us)
    - [ Integrating Maps ](https://www.bitovi.com/academy/learn-react-native/google-maps.html?hsLang=en-us)
    - [ Performance and Optimization ](https://www.bitovi.com/academy/learn-react-native/performance-optimization.html?hsLang=en-us)
    - [ Building React Native Apps ](https://www.bitovi.com/academy/learn-react-native/building.html?hsLang=en-us)
    - [ Publishing and Updating ](https://www.bitovi.com/academy/learn-react-native/publishing-and-updating.html?hsLang=en-us)
- [ Learn Web Components ](https://www.bitovi.com/academy/learn-web-components.html?hsLang=en-us)
- [ Agile Program Management With Jira ](https://www.bitovi.com/academy/learn-agile-program-management-with-jira.html?hsLang=en-us)
- [ Learn RxJS ](https://www.bitovi.com/academy/learn-rxjs.html?hsLang=en-us)
- [ Giving a Training ](https://www.bitovi.com/academy/training.html?hsLang=en-us)
- [ Learn Technology Consulting ](https://www.bitovi.com/academy/learn-technology-consulting.html?hsLang=en-us)
- [ Learn React ](https://www.bitovi.com/academy/learn-react.html?hsLang=en-us)
- [ Learn NgRx ](https://www.bitovi.com/academy/learn-ngrx.html?hsLang=en-us)
- [ Learn Graphql ](https://www.bitovi.com/academy/learn-graphql.html?hsLang=en-us)
- [ Learn Docker ](https://www.bitovi.com/academy/learn-docker.html?hsLang=en-us)
- [ Learn CanJS ](https://www.bitovi.com/academy/learn-canjs.html?hsLang=en-us)
- [ Learn Angular ](https://www.bitovi.com/academy/learn-angular.html?hsLang=en-us)
- [ Advanced TypeScript ](https://www.bitovi.com/academy/advanced-typescript.html?hsLang=en-us)

[View More Courses](https://www.bitovi.com/academy/#courses) [ ]

# Managing State with useState `page`

Work with React’s useState Hook to manage a component’s state.

## Overview

In this section, you will:

- Get an overview of state management.
- Cover the fundamentals of React Hooks.
- Review the Rules of Hooks.
- Learn about the `useState` Hook.
- Create custom Hooks.

## Objective: Toggle between light and dark mode

We will be setting up the application to switch between light mode and dark mode:

![Screenshot of the application when it is in light mode.](https://bitovi.github.io/academy/static/img/react-native/10-managing-state/lightMode.png) ![Screenshot of the application when it is in dark mode.](https://bitovi.github.io/academy/static/img/react-native/10-managing-state/darkMode.png)

### Overview of state management

State in React Native is a crucial concept, as it represents the parts of an app that can change over time. Each component can have its state, allowing them to maintain and manage their data independently. When the state changes, React Native re-renders and update the native UI components if it needs to.

There are different types of state within an application:

- **Global State:** This refers to data that is shared between multiple components. In React Native, global state can be managed using Context API or state management libraries; this is covered in the previous lesson [Using React Context](https://www.bitovi.com/academy/learn-react-native/react-context.html?hsLang=en-us).
- **Local State:** This is data we manage in the component that uses it. Local state is managed in React Native using the `useState` Hook.
- **UI State:** This is a subset of Local State, but is limited to minor UI effects, such as the visibility of a drawer or open section of an accordion.

### Intro to React Hooks

We’ve mentioned before that `useState` is a Hook for managing state, but what does that mean?

React Hooks (referred to as just Hooks for the rest of this training) are special functions that allow us to “hook” into React Native functionality. Hooks provide us with many conveniences like sharing stateful logic between components and simplifying what would be otherwise complex components.

We’ve already seen and used a Hook while building Place My Order! Do you remember this code from earlier?

```
import { createContext, useContext, useMemo } from "react"

import theme, { Theme } from "./theme"

interface ThemeContext {
  theme: Theme
}

const Context = createContext<ThemeContext>({
  theme,
})

const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({
  children,
}) => {
  const value = useMemo(() => ({ theme }), [])

  return <Context.Provider value={value}>{children}</Context.Provider>
}

export default ThemeProvider

export function useTheme(): Theme {
  const { theme } = useContext(Context)

  return theme
}

```

The `useContext` and `useMemo` Hook from `react` allowed us to optimize the performance of our applications by efficiently managing context and memoizing expensive computations respectively.

### The Rules of Hooks

React Native imposes several rules around the use of Hooks:

- **First,** only call Hooks from React Native function components or your custom Hooks.
- **Second,** all the Hooks in a React Native function must be invoked in the same order every time the function runs, so no Hooks can occur after an `if`, `loop`, or `return` statement. Typically this means all Hooks are placed at the top of the React Native function body.
- **Third,** Hooks must be named by prefixing their functionality with `use` (e.g. `useContext`).

### The useState Hook

We can store the state that persists through component rendering with the `useState` Hook. You can set the initial state value when the component **first** renders by providing the value as an argument to the Hook. If you do not provide a value the initial state value will be `undefined`.

This example shows a `useState` Hook being set with an initial value of `""`:

```
import { ChangeEvent, useState } from "react"
import { Text, TextInput, View } from "react-native"

const NameField: React.FC = () => {
  const [value, setValue] = useState<string>("")

  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    setValue(event.target.value)
  }

  return (
    <View>
      <Text>Name</Text>
      <TextInput
        onChangeText={handleChange}
        value={value}
        style={{ borderWidth: 1, borderColor: "gray", padding: 10 }}
      />
    </View>
  )
}

```

As you can see in the previous example, `useState` returns an array with two elements: the first is the current state value of the Hook, and the second is a setter function that is used to update the state value.

In the following code, the value is being rendered and the setter is being used to keep track of which input value the user has typed:

```
import { ChangeEvent, useState } from "react"
import { Text, TextInput, View } from "react-native"

const NameField: React.FC = () => {
  const [value, setValue] = useState<string>("")

  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    setValue(event.target.value)
  }

  return (
    <View>
      <Text>Name</Text>
      <TextInput
        onChangeText={handleChange}
        value={value}
        style={{ borderWidth: 1, borderColor: "gray", padding: 10 }}
      />
    </View>
  )
}

```

Every time a `useState`’s setter is invoked with a new value, React Native compares the new value with the current value. If the values are the same, nothing happens; **if the values are different, React Native will rerender the component** so the new state value can be used to update the component.

In the example above, when the user types, the `NameField` component is rendered again, and the `TextInput` is updated with the current value.

### What are custom Hooks?

React Native’s Hooks API provides a powerful and flexible way to encapsulate and reuse functionality across our components. While React Native comes with a set of built-in Hooks, we can also create our own custom Hooks. This allows us to abstract component logic into reusable functions. Custom Hooks are particularly useful when we find ourselves repeating the same logic in multiple components.

Custom Hooks are JavaScript functions that can use other React Hooks and provide a way to share logic across multiple components. Like built-in Hooks, custom Hooks must adhere to React’s rules of Hooks. The naming convention for custom Hooks is to start with `use`, like `useCustomHook`.

### Why use custom Hooks?

Putting stateful logic into a custom Hook has numerous benefits:

**Separation of concerns:** Custom Hooks allow you to separate complex logic from the component logic. This makes your main component code cleaner and more focused on rendering UI, while the custom Hook handles the business logic or side effects. It aligns well with the principle of single responsibility, where a function or module should ideally do one thing only.

**Simplifying components:** If your component is becoming too large and difficult to understand, moving some logic to a custom Hook can simplify it. This not only improves readability but also makes it easier for other developers to grasp what the component is doing.

**Easier testing and maintenance:** Isolating logic into custom Hooks can make your code easier to test and maintain. Since Hooks are just JavaScript functions, they can be tested independently of any component. This isolation can lead to more robust and reliable code.

**Reusability:** One of the primary reasons for creating custom Hooks is reusability. You might find yourself repeating the same logic in different components—for example, fetching data from an API, handling form input, or managing a subscription. By refactoring this logic into a custom Hook, you can easily reuse this functionality across multiple components, keeping your code DRY (Don’t Repeat Yourself).

### How to create a custom Hook

To create a custom Hook, you start by defining a function that starts with `use`. This Hook can call other Hooks and return whatever value is necessary.

Let’s look at the provided Hook below that keeps track of a boolean state, and also provides a function for toggling that state:

```
import { useState } from "react"

export function useToggle(intialValue = true) {
  const [on, setOn] = useState(intialValue)

  const handleToggle = (value?: unknown) => {
    if (typeof value === "boolean") {
      setOn(value)
    } else {
      setOn(!on)
    }
  }

  return [on, handleToggle]
}

```

In the example above, you can see that our `useToggle` Hook is a function that has an internal `useState` to keep track of the toggle’s on/off status. This Hook has a `handleToggle` function for changing its internal state. Lastly, we can see that the `useToggle` Hook returns an array with the `on` status and the `handleToggle` function.

### How to use a custom Hook

How would we use this Hook? Let’s take a look at this example:

```
import React from "react"
import { View, Text, Switch } from "react-native"

import { useToggle } from "./useToggle"

const Toggle: React.FC = () => {
  const [active, toggleActive] = useToggle(true)

  return (
    <View>
      <Switch onValueChange={toggleActive} value={active} />
      <Text>{active ? "On" : "Off"}</Text>
    </View>
  )
}

export default Toggle

```

In this component, we call our `useToggle` Hook with the initial state (`true`). Our Hook returns the `active` state and `toggleActive` function for changing the on/off state.

This is how we can create our custom `useToggle` Hook and call it in our components, just like React’s built-in Hooks!

### Using the `Appearance` module

The `Appearance` module in React Native allows you to access the user’s preferred color scheme (light or dark). This helps in creating responsive designs that adapt to user preferences without requiring manual theme switches in your app.

To get the current theme, use the `getColorScheme` method. It returns either `'light'`, `'dark'`, or `null` if the preference is not set.

```
import { Appearance } from "react-native"

const colorScheme = Appearance.getColorScheme()

if (colorScheme === "dark") {
  // Dark mode logic
} else {
  // Light mode logic
}
```

### Setup

✏️ Update **src/design/theme/theme.ts** to be:

```
import { TextStyle } from "react-native"

interface Palette {
  main: string
  soft: string
  strong: string
  contrast: string
}

export interface Theme {
  palette: {
    screen: Palette
    primary: Palette
    secondary: Palette
  }
  spacing: {
    none: 0
    xs: number
    s: number
    m: number
    l: number
    xl: number
  }
  typography: {
    title: TextStyle
    heading: TextStyle
    body: TextStyle
    label: TextStyle
  }
}

export type ThemeMargin =
  | keyof Theme["spacing"]
  | [keyof Theme["spacing"], keyof Theme["spacing"]]
export type ThemePadding =
  | keyof Theme["spacing"]
  | [keyof Theme["spacing"], keyof Theme["spacing"]]

const light: Theme = {
  palette: {
    screen: {
      main: "#ffffff",
      soft: "#e0e0e0",
      strong: "#ffffff",
      contrast: "#222222",
    },
    primary: {
      main: "#007980",
      soft: "#00a5ad",
      strong: "#006166",
      contrast: "#ffffff",
    },
    secondary: {
      main: "#ca2f35",
      soft: "#d93237",
      strong: "#a3262b",
      contrast: "#ffffff",
    },
  },
  spacing: {
    none: 0,
    xs: 4,
    s: 8,
    m: 16,
    l: 24,
    xl: 40,
  },
  typography: {
    title: {
      fontSize: 21,
      fontWeight: "500",
    },
    heading: {
      fontSize: 24,
      fontWeight: "500",
    },
    body: {
      fontWeight: "normal",
    },
    label: {
      fontSize: 12,
      fontWeight: "bold",
    },
  },
}

const dark: Theme = {
  ...light,
  palette: {
    ...light.palette,
    screen: {
      main: "#29292c",
      soft: "#565659",
      strong: "#000000",
      contrast: "#ffffff",
    },
    primary: {
      ...light.palette.primary,
      soft: "#003a3d",
      strong: light.palette.primary.soft,
    },
    secondary: {
      ...light.palette.secondary,
      soft: "#811e22",
      strong: light.palette.secondary.soft,
    },
  },
}

export default {
  light,
  dark,
}

```

✏️ Update **src/design/theme/ThemeProvider.tsx** to be:

```
import { useState, createContext, useContext, useMemo } from "react"
import { Appearance } from "react-native"

import themes, { Theme } from "./theme"

type Mode = keyof typeof themes

interface ThemeContext {
  mode: Mode
  setMode: (mode: Mode) => void
}

// Exercise: Update `Context` to set default values for `mode` and `setMode`.
const Context = createContext<ThemeContext>({
  theme,
})

export interface ThemeProviderProps {
  children: React.ReactNode
}

// Exercise: Update `ThemeProvider` to use `useState`, so the user can switch between the 2 modes.
const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
  const value = useMemo(() => ({ theme }), [])

  return <Context.Provider value={value}>{children}</Context.Provider>
}

export default ThemeProvider

// Exercise: Update `useTheme` to return 1 theme based on the `mode` that is stored in the context.
export function useTheme(): Theme {
  const { theme } = useContext(Context)

  return theme
}

// Exercise: Update `useThemeMode` to return `mode` and `setMode`.
export function useThemeMode(): {
  mode: Mode
  setMode: (mode: Mode) => void
} {
  //
}

```

✏️ Update **src/screens/StateList/StateList.tsx** to be:

```
import Card from "@shared/design/Card"
import Screen from "@shared/design/Screen"
import { useThemeMode } from "@shared/design/theme"
import Typography from "@shared/design/Typography"
import { StyleSheet, Switch, View } from "react-native"

import ListItem from "./components/ListItem"

const states = [
  {
    name: "Illinois",
    short: "IL",
  },
  {
    name: "Wisconsin",
    short: "WI",
  },
]

const StateList: React.FC = () => {
  // Exercise: Display the Switch component to allow users to toggle.

  return (
    <Screen>
      <Card>
        <Typography variant="heading">Place My Order: Coming Soon!</Typography>
      </Card>
      {states?.length ? (
        states.map((state) => <ListItem key={state.short} name={state.name} />)
      ) : (
        <Typography>No states found</Typography>
      )}
      {/* Exercise: Using the recently created `useThemeMode` Hook, combine it with the `Switch` component. */}
    </Screen>
  )
}

const styles = StyleSheet.create({
  row: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
  },
})

export default StateList

```

### Verify

✏️ Update **src/design/theme/ThemeProvider.test.tsx** to be:

```
import {
  render,
  screen,
  renderHook,
  waitFor,
} from "@testing-library/react-native"
import { View, Text } from "react-native"

import ThemeProvider, { useTheme, useThemeMode } from "./ThemeProvider"

describe("Design/Theme", () => {
  describe("ThemeProvider", () => {
    it("renders children", async () => {
      render(
        <ThemeProvider>
          <Text>Hello!</Text>
        </ThemeProvider>,
      )

      expect(screen.getByText(/Hello/)).toBeOnTheScreen()
    })
  })

  describe("ThemeContext", () => {
    const TestComponent: React.FC = () => {
      const theme = useTheme()

      return (
        <View>
          <Text>{theme.palette.primary.main}</Text>
        </View>
      )
    }

    it("exposes context properties", async () => {
      render(<TestComponent />)

      expect(screen.getByText(/#007980/)).toBeOnTheScreen()
    })

    describe("useThemeMode", () => {
      it("toggles the theme", async () => {
        const { result } = renderHook(() => useThemeMode(), {
          wrapper: ThemeProvider,
        })

        expect(result.current.mode).toBe("light")

        result.current.setMode("dark")

        await waitFor(() => {
          expect(result.current.mode).toBe("dark")
        })
      })
    })
  })
})

```

✏️ Update **src/screens/StateList/StateList.test.tsx** to be:

```
import { render, screen, fireEvent } from "@testing-library/react-native"

import StateList from "./StateList"

const mockSetMode = jest.fn()

jest.mock("@shared/design/theme", () => ({
  ...jest.requireActual("@shared/design/theme"),
  useThemeMode: () => ({
    mode: "light",
    setMode: mockSetMode,
  }),
}))

describe("Screens/StateList", () => {
  it("renders", async () => {
    render(<StateList />)
    expect(screen.getByText(/Illinois/i)).toBeOnTheScreen()
    expect(screen.getByText(/Wisconsin/i)).toBeOnTheScreen()
  })

  it("switches to dark mode", () => {
    render(<StateList />)

    const switchElement = screen.getByRole("switch")
    expect(switchElement.props.value).toBe(false)

    fireEvent(switchElement, "onValueChange", true)
    expect(mockSetMode).toHaveBeenCalledWith("dark")
  })
})

```

### Exercise

Refactor **src/design/theme/ThemeProvider.tsx**:

- Update `Context` to set default values for `mode` and `setMode`.
- Update `ThemeProvider` to use `useState`, so the user can switch between the 2 modes.
- Update `useTheme` to return 1 theme based on the `mode` that is stored in the context.
- Update `useThemeMode` to return `mode` and `setMode`.

Refactor **src/screens/StateList/StateList.tsx**:

- Display the `Switch` component to allow users to toggle.
- Using the recently created `useThemeMode` Hook, combine it with the `Switch` component.

### Solution

If you’ve implemented the solution correctly, the tests will pass when you run `npm run test`!

Click to see the solution

✏️ Update **src/shared/design/theme/ThemeProvider.tsx** to be:

```
import { useState, createContext, useContext, useMemo } from "react"
import { Appearance } from "react-native"

import themes, { Theme } from "./theme"

type Mode = keyof typeof themes

interface ThemeContext {
  mode: Mode
  setMode: (mode: Mode) => void
}

const Context = createContext<ThemeContext>({
  mode: "light",
  setMode: () => undefined,
})

export interface ThemeProviderProps {
  children: React.ReactNode
}

const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
  const [mode, setMode] = useState<Mode>(Appearance.getColorScheme() || "light")

  const value = useMemo(() => ({ mode, setMode }), [mode])

  return <Context.Provider value={value}>{children}</Context.Provider>
}

export default ThemeProvider

export function useTheme(): Theme {
  const { mode } = useContext(Context)

  return themes[mode]
}

export function useThemeMode(): {
  mode: Mode
  setMode: (mode: Mode) => void
} {
  const { mode, setMode } = useContext(Context)

  return { mode, setMode }
}

```

✏️ Update **src/screens/StateList/StateList.tsx** to be:

```
import Card from "@shared/design/Card"
import Screen from "@shared/design/Screen"
import { useThemeMode } from "@shared/design/theme"
import Typography from "@shared/design/Typography"
import { StyleSheet, Switch, View } from "react-native"

import ListItem from "./components/ListItem"

const states = [
  {
    name: "Illinois",
    short: "IL",
  },
  {
    name: "Wisconsin",
    short: "WI",
  },
]

const StateList: React.FC = () => {
  const { mode, setMode } = useThemeMode()

  return (
    <Screen>
      <Card>
        <Typography variant="heading">Place My Order: Coming Soon!</Typography>
      </Card>
      {states?.length ? (
        states.map((state) => <ListItem key={state.short} name={state.name} />)
      ) : (
        <Typography>No states found</Typography>
      )}

      <Card>
        <View style={styles.row}>
          <Typography variant="heading">Dark mode</Typography>
          <Switch
            onValueChange={(value) => setMode(value ? "dark" : "light")}
            value={mode === "dark"}
          />
        </View>
      </Card>
    </Screen>
  )
}

const styles = StyleSheet.create({
  row: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
  },
})

export default StateList

```

## Next steps

Next, we will learn how to switch screens with [Navigation in React Native](https://www.bitovi.com/academy/learn-react-native/navigation.html?hsLang=en-us).

###### On this page...

###### Get help

If you need [help](https://discord.gg/J7ejFsZnJ4) with an exercise, please reach out to us on [Discord](https://discord.gg/J7ejFsZnJ4)

If you find a bug, please [create an issue](https://github.com/bitovi/academy/issues/new) or email [contact@bitovi.com](mailto:contact@bitovi.com?Subject=Training%20Suggestion)

## Join the Bitovi Newsletter

 Do you want to receive updates about new Bitovi Academy courses, Bitovi open source projects, and dev community news? If so, please provide your email. We won’t spam you or give it away for any reason!  
*By providing your email you agree to receive communications from Bitovi*

![](https://bitovi.github.io/academy/static/img/close.svg)

```json
{
     "@context": "http://schema.org",
     "@type": "Organization",
     "mainEntityOfPage":{
          "@type":"WebPage",
          "@id":"https://www.bitovi.com/academy/learn-react-native/managing-state.html",
          "description": "Work with React’s useState Hook to manage a component’s state. 
"
     },
     "url": "http://bitovi.com",
     "logo": "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg",
     "image": "https://www.bitovi.com/hubfs/bitovi-logo-x2.png",
     "name": "Bitovi Web App Consulting",
     "alternateName": "Bitovi",
      "naics": "541511",
      "description": "Bitovi is a UX, UI design and front-end JavaScript development consulting company",
     "address": {
          "@type": "PostalAddress",
          "streetAddress": "1134 Pine Tree Lane ",
          "addressLocality": "Libertyville",
          "addressRegion": "IL",
          "addressCountry": "United States",
          "postalCode": "60048"
     },
     "areaServed": {
          "@type": "GeoCircle",
          "geoMidpoint": {
               "@type": "GeoCoordinates",
               "latitude": "41.8781",
               "longitude": "87.6298"
          },
          "geoRadius": "5000 km"
     },
     "telephone": "312-620-0386",
     "email": "contact@bitovi.com",
     "sameAs": [
          "https://www.facebook.com/BitoviLLC/",
          "https://twitter.com/bitovi",
          "https://www.linkedin.com/company/bitovi"
     ]
}
```