---
title: ThemeProvider
sidebar_position: 1
---

The previous solution works great for only one component, but imagine having to
do this for every component you want custom styles for. That could get a bit
tedious to manage. Thankfully, there's a better way to do this. React Native
Elements ships with a 3 utilities for large-scale theming.

Firstly you'll want to set up your `ThemeProvider`.

```jsx
import { ThemeProvider, Button, createTheme } from '@rneui/themed';

const theme = createTheme({
  components: {
    Button: {
      raised: true,
    },
  },
});

// Your App
const App = () => {
  return (
    <ThemeProvider theme={theme}>
      <Button>My Button</Button>
    </ThemeProvider>
  );
};
```

:::note
If you do not specify `theme` in ThemeProvider, it would use [defaultTheme](./theme_object#default-light-colors)
:::

The example above achieves the same goals as the first example — apply the same
styles to multiple instances of `Button` in the app. However this example
applies the `raised` prop to every instance of `Button` inside the component
tree under `ThemeProvider`. Both of these buttons will have the `raised` prop
set to true.

This is extremely convenient and is made possible through
[React's Context API](https://reactjs.org/docs/context.html).

:::note
To theme subcomponents such as `ListItem.Title`, in your theme remove the dot and list them as "ListItemTitle"
:::

---

### use-theme hook

Hook returns `theme`, `updateTheme` & `replaceTheme` from ThemeProvider context or default theme if you did not wrap application with ThemeProvider.

```tsx
import { useTheme } from '@rneui/themed';

function Demo() {
  const { theme, updateTheme } = useTheme();
  return (
    <View style={{ background: theme.colors.primary }}>
      <Button onPress={() => updateTheme({ colors: { primary: 'red' } })} />
    </View>
  );
}
```

The updateTheme function merges the theme passed in with the current theme.

```tsx
updateTheme({
  lightColors: {
    primary: 'purple',
  },
});
```

The `replaceTheme` function merges the theme passed in with the default theme.

---

### use-theme-mode hook

You can get current theme mode (light or dark) and update it using setMode function from useThemeMode hook.

```tsx
import { useThemeMode } from '@rneui/themed';

function Demo() {
  const { mode, setMode } = useThemeMode();

  return <Button onPress={() => setMode('dark')} title={mode} />;
}
```

### make-styles

If you want to keep your styles outside the component use `makeStyles()` (hook generator) to reference the `theme` and component props (optional param).

```tsx
import React from 'react';
import { Text } from 'react-native';
import { makeStyles } from '@rneui/themed';

type Props = {
  fullWidth?: boolean;
};

const MyComponent = (props: Props) => {
  const styles = useStyles(props);

  return (
    <View style={styles.container}>
      <Text style={{ color: theme.colors.primary }}>Yo!</Text>
    </View>
  );
};

const useStyles = makeStyles((theme, props: Props) => ({
  container: {
    background: theme.colors.white,
    width: props.fullWidth ? '100%' : 'auto',
  },
  text: {
    color: theme.colors.primary,
  },
}));
```

Don't want to wrap your components with `withTheme`? You can use the `ThemeConsumer` component
which uses render props!

```tsx
import React from 'react';
import { Text } from 'react-native';
import { ThemeConsumer } from '@rneui/themed';

const MyComponent = () => (
  <ThemeConsumer>
    {({ theme }) => (
      <Text style={{ color: theme.colors.primary }}>Yo!</Text>;
    )}
  </ThemeConsumer>
)
```

### Dark Mode

```tsx
import { useColorScheme } from 'react-native-appearance';

const theme = createTheme({
  lightColors: {
    primary: '#899656',
  },
  darkColors: {
    primary: '#344512',
  },
  mode: 'light',
});

const ColorScheme = ({ children }) => {
  const colorMode = useColorScheme();
  const { theme } = useTheme();
  const { setMode } = useThemeMode();

  React.useEffect(() => {
    setMode(colorMode);
  }, [colorMode]);

  return (
    <View style={{ backgroundColor: theme.colors.background }}>{children}</View>
  );
};

const App = () => {
  return (
    <ThemeProvider theme={theme}>
      <ColorScheme>{/*  */}</ColorScheme>
    </ThemeProvider>
  );
};
```
