明智地在 React Native 中实现深色模式

Implementing dark mode in React Native sensibly

我正在尝试为我的 React Native 应用添加深色模式支持。我将在 mobx 商店 mode 中有一个标志,视情况而定 lightdark

为了将其与现有应用程序相关联,我希望尽可能保留现有样式定义并仅在需要时覆盖(而不是将所有内容重写为浅色和深色主题)。

我想出了一个类似下面的函数来 return 基于当前模式的适当样式:

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;
}

视图将呈现如下:

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

风格:

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

现在这可行了,但我不确定它是否会以我现在不知道的性能成本为代价(使用函数,使用样式对象而不是 StyleSheet.create... ),或者如果有更简单的方法我看不到树。我也不想对每个元素都进行三元内联。

我建议看一下 ReactJS 中的 Context api。它为维护组件树周围的全局数据提供了一个很好的开箱即用解决方案。

您可以使用 React.createContext()react-native-paper

这个模块让改变背景变得简单,只需一个按钮。我给你做了一个简单的例子。

我做了一个example link.

我最终采取了稍微不同的方式,因为我会根据当前模式添加额外的样式,例如

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

然后使用主题变量覆盖

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

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