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);
実際の画面はこんな感じで切り替わります。