Cover image for react-native-elementsで動的にThemeを変更する
react-native

react-native-elementsで動的にThemeを変更する

February 13, 2019

3 min read

mitsuruogMitsuru Ogawa

react-native プロダクトでベースとなる UI コンポーネントライブラリを探していたら、ちょうどいいタイミングで react-native-elements が v1 になったので使ってみることにしました。

v1 の目玉機能の一つに Theme があります。 基本的な使い方は、自身でカスタム Theme を作成してからThemeProviderにその Theme を渡すだけで動くのですが、一度設定した Theme をプログラムにて変更する場合に一癖あったので、その辺りを紹介します。

Theme についての公式のドキュメントはこちらです。

Theme の基本的な使い方

まずカスタム Theme を作成します。Theme のオブジェクトフォーマットについてはこちらを参照してください。

const theme = {
  colors: {
    primary: "green",
  },
};

これを App.js などの上位のコンポーネントにThemeProviderを置いて Theme を設定して読み込ませれば大丈夫です。

// App.js

  ...

  render() {
    return (
      <ThemeProvider theme={theme}>
        <AppRoute /> // react-native-router-fluxなどのRoute設定コンポーネント
      </ThemeProvider>
    );
  }

Theme を動的に変更する

さて、Theme を動的に変更してみましょう。ThemeProviderthemeを props に持っているので、これを変更すれば Theme も変更できそうですが、実際には変更できません。

- Question: Is it possible to toggle active Theme at runtime? · Issue #1714 · react-native-training/react-native-elements

props での Theme の変更をゆるしてしまった場合、全てのコンポーネント  ツリーのコンポーネントが再描画されてしまうため、これを避けるためにwithTheme HOC(High Order Component)かThemeConsumerを使ってupdateThemeを呼び出す必要があるようです。

今回はwithThemeを使ってみました。

withTheme を使った Theme の変更

まず Theme の変更をトリガーするコンポーネントをwithThemeでラップします。ラップされたコンポーネントには props にupdatethemethemeが渡されてくるので、updateThemeに変更後の Theme を設定します。

// Child.js
const Child = (props) => {
  return (
    <View>
      <Button
        title="Change theme"
        onPress={() => props.updateTheme({ colors: { primary: "blue" } })}
      />
    </View>
  );
};

export default withTheme(Child);

実際の画面はこんな感じで切り替わります。