Home > OS >  React Native - What's the best way to provide a global theme?
React Native - What's the best way to provide a global theme?

Time:11-11

I've started using RN recently and have been doing some research on the implementation of themes and/or a dark-light mode. Here's roughly how I understand the two main options so far:

  • Context: Easy setup and can be accessed via hook inside the component that needs it. I count things like the React Navigation themes since that works, in essence, the same way(?)
  • Styled Components: Essentially just replacing the components with custom ones that access the current theme and that can then be set up to change their props on toggle if needed.

What I don't like about context, is that (the way I understand it) it wouldn't let me access the theme when using a StyleSheet, since that's outside the component. With the styled components on the other hands I'm not sure if I can cover all options inside my custom components, wouldn't I still need some sort of hook in each component anyway?

I was also thinking about just saving the current theme into my Store (in my case Zustand), together with an action that lets me toggle to a dark-mode. But so far, I haven't really seen anyone else do that, is there a downside to doing it that way?

CodePudding user response:

It's not hard to pass context to your stylesheet, it just requires a bit of extra boilerplate. Something like the below:

import ThemeContext from '<path>';

export default () => {
  const theme = useContext(ThemeContext);
  const stylesWithTheme = styles(theme);

  return <Text style={stylesWithTheme.text>Hi</Text>;
}

const styles = theme => StyleSheet.create({
  text: {
    color: themeStyles.color[theme];
  }
});

const themeStyles = {
  color: {
    dark: '#FFF',
    light: '#000',
  },
};

I don't think using styled components would be a big departure from the above scheme.

If you did store your theme in state, and define your styles within the body of the component, that could be a savings in boilerplate. It's up to you whether having your styles in the component body is acceptable.

Side note, if you're already using a state manager, I would recommend not mixing it with the Context API without knowing more. It's simpler to have one solution there.

  • Related