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 を動的に変更してみましょう。ThemeProviderはthemeを props に持っているので、これを変更すれば Theme も変更できそうですが、実際には変更できません。
props での Theme の変更をゆるしてしまった場合、全てのコンポーネント ツリーのコンポーネントが再描画されてしまうため、これを避けるためにwithTheme HOC(High Order Component)かThemeConsumerを使ってupdateThemeを呼び出す必要があるようです。
今回はwithThemeを使ってみました。
withTheme を使った Theme の変更
まず Theme の変更をトリガーするコンポーネントをwithThemeでラップします。ラップされたコンポーネントには props にupdatethemeとthemeが渡されてくるので、updateThemeに変更後の Theme を設定します。
// Child.js
const Child = (props) => {
return (
<View>
<Button
title="Change theme"
onPress={() => props.updateTheme({ colors: { primary: "blue" } })}
/>
</View>
);
};
export default withTheme(Child);
実際の画面はこんな感じで切り替わります。

