2

I'm trying to add dark mode support to my React Native app. I will have a flag in a mobx store mode which will be light or dark as appropriate.

In order to tie this into an existing app, I wanted to, if possible, keep the existing style definitions and only override when needed (rather than rewrite everything to a light and a dark theme).

I came up with a function like the following to return the appropriate styles based on the current mode:

function getStyle(style) {
  let ret = [styles[style]];
  if (
    styles.hasOwnProperty(Store.mode) &&
    styles[Store.mode][style] !== "undefined"
  ) {
    ret.push(styles[Store.mode][style]);
  }
  return ret;
}

The view would be rendered as such:

...
<View style={getStyle("container")}>
  <Text style={getStyle("text")}>Some text</Text>
</View>
...

The styles:

const styles = {
  dark: {
    container: {
      backgroundColor: "#000"
    },
    text: {
      color: "#fff"
    }
  },
  container: {
    padding: 20,
    backgroundColor: "#fff"
  },
  text: {
    fontSize: 18,
    color: "#000"
  }
};

Now this works, but I'm not sure if it's coming at some performance cost I'm unaware of right now (the use of the function, using a style object instead of StyleSheet.create...), or if there's a much simpler way I can't see for the trees. I'd rather not do a ternary inline on every element either.

besthorse
  • 31
  • 1
  • 4

3 Answers3

1

I ended up going a slightly different way, in that I'd add extra styles depending on the current mode, e.g.

<View style={[styles.container, theme[Store.mode].container]}>
  <Text style={[styles.text, theme[Store.mode].text]}>Some text</Text>
</View>

And then using the theme var to override

const theme = {
  light: {},
  dark: {
    container: {
      backgroundColor: "#000"
    },
    text: {
      color: "#fff"
    }
  }
};

const styles = {
  container: {
    padding: 20,
    backgroundColor: "#fff"
  },
  text: {
    fontSize: 18,
    color: "#000"
  }
};
besthorse
  • 31
  • 1
  • 4
0

I would suggest taking a look at the Context api in ReactJS. It gives a good out of the box solution for maintaining global data around the component tree.

johnborges
  • 2,422
  • 20
  • 33
0

You can use React.createContext() and react-native-paper

This module makes it simple to change the background with just a button. I made a simple example for you.

I made an example link.

gif i made

hong developer
  • 13,291
  • 4
  • 38
  • 68