
NativeBase 3.0はReact Nativeアプリのための楽しいUI開発キット
NativeBase 3.0がリリース
NativeBaseはReact Native向けに開発されたUIライブラリです。先日公開された3.0から大幅に実装が変わり、Styled SystemベースのUtility Style Propsが使えるようになりました。
また、iOS/Androidネイテイブに加えてウェブ(RN for Web)での動作もサポートされるようになり、ソースコードをプラットフォーム間でシェアしたい我々のような開発チームに要注目の内容になっています(※ウェブ版はアルファ・リリース)。
今回は、そんなNativeBaseの実力を探るべく、弊社のプロダクトの機能の一部をお試し実装してみました。
Utility Firstってなに?という方のために
翻訳:CSSユーティリティクラスと「関心の分離」(いかにしてユーティリティファーストにたどり着いたか)
https://yuheiy.hatenablog.com/entry/2020/05/25/021342
はじめてこのブログを読んだ方へ: U-motionとは?
U-motionは牛の首につけたセンサーを使って活動内容を記録、AIの力で健康状態を解析して畜産農家さんをサポートするモニタリング・システムです。
https://www.desamis.co.jp/product/
NativeBase 3.0でU-motionのUIを実装してみた
iOS版(ダークモード)
牛の監視システムU-motionのアラート・ダッシュボードをもとに一部簡略化して実装した画面がこちらになります。
管理する牛の様々なアラートを一覧表示する機能です。この画面から体調の悪い牛などをチェックして場合によっては治療などの処置を行っていきます。
NativeBase 3.0はダークモードのテーマ切り替えに対応しているので、右上にモード切り替えスイッチを配置してあります。以下、Android版とウェブ版のスクリーンショットです。
Android
ウェブ版
ソースコードの一部
// ダッシュボード
<Dashboard.Section title='分娩'>
<Dashboard.Row>
<Dashboard.Item
label='分娩兆候(未確認)'
value={alertSummary.CALVING}
unit='頭'
onPress={() => onPressItem('CALVING')}
/>
<Dashboard.Item
label='確認済み'
value={alertSummary.CALVING_CONFIRMED}
unit='頭'
onPress={() => onPressItem('CALVING_CONFIRMED')}
/>
</Dashboard.Row>
<Dashboard.Row>
<Dashboard.Item
label='分娩センサー脱落'
value={alertSummary.CALVING_SENSOR_DROPPD}
unit='頭'
onPress={() => onPressItem('CALVING_SENSOR_DROPPED')}
/>
<Dashboard.BlankItem />
</Dashboard.Row>
</Dashboard.Section>
// ダッシュボード項目のコンポーネント
export const Item: React.FC<ItemProps> = ({ label, value, unit, onPress }) => {
return (
<Column
backgroundColor={useColorModeValue('white', 'black')}
flexGrow={1}
flexShrink={1}
borderRadius='lg'
borderWidth={1}
opacity={value ? 1.0 : 0.5}
borderColor={useColorModeValue('gray.300', 'white')}
shadow={1}
width='100%'
>
<Pressable
onPress={onPress}
paddingTop={3}
paddingBottom={2}
paddingX={3}
>
<Text fontWeight='bold'>{label}</Text>
<Box height={3} />
<HStack alignItems='center' justifyContent='space-between'>
<Text fontSize='3xl' fontWeight='bold'>
{value ? value.toString() : 0}
<Box width={1} />
<Text fontSize='lg' fontWeight='bold'>
{unit}
</Text>
</Text>
<Box>
{value && (
<Icon
as={<Ionicons name='chevron-forward-outline' />}
size={useToken('fontSizes', 'lg')}
/>
)}
</Box>
</HStack>
</Pressable>
</Column>
);
};
Android、iOS、さらにウェブでほぼ意図した通りのUIを動作させることができました。
実装して分かったこと、感じたこと
Utility PropsはUI実装に必要な要素が揃っていて実用的
アラート表示では
・牛の頭数が「4」「頭」とそれぞれ異なるフォントサイズ
・レイアウトは下揃え
になります。
さらにタップできる項目を示す「>」のアローアイコンは縦位置が中央揃えで1行のなかに複雑なレイアウト指定がありますが、Flex-Boxと同等のプロパティーを使って実装することができました。
HStack、VStackが便利
NativeBase 3.xにはHStack、VStackなどのレイアウト系コンポーネントが標準で準備されていて、いちいちUtility Propsを指定せずにおおまかな枠組みを作れるのも良いところだと感じました。これによってコード作成のスピードが上がるだけでなく、コード量がコンパクトになり、またコードの見通しが良くなることが期待できそうです。
Utility Style Propsの記述がわかりやすい
サンプル・コードにあるように、fontSize、paddingX、paddingY、fontWeightなど長めの表記を利用することが可能です。TailwindCSSなどと比較すると「解読」がそれほど大変ではないコードを記述することができます。NativeBaseはコンポーネント・ライブラリなので、そもそもプロパティーでスタイルを修正する必要があまりなく、直接の比較をするのは意味がないとも思いますが、後述するようなUI開発のベースキットとして考えるとこのバランス感覚は心地よいと感じました。
まとめ: コンポーネントのカタログ重視から、独自のUIを再構築しやすいか?という発想の転換
U-motion開発チームではウェブ版のほかにアラートのプッシュ通知を受信できるスマホ・アプリケーションを開発・提供しており、React Native Paperを採用してUIを構築しています。ライブラリ選定時はReact Native Paperが提供するボタンやカードなどのコンポーネントで我々が望むUIを実現できるか、カタログを入念にチェックしました。このライブラリのおかげでスピード感のある開発ができていますが、徐々にオリジナルUIを構築するケースも増えてきました。
React Native PaperはpaddingやmarginなどをカスタマイズするUtility Propsを提供しておらず、React NativeのStyleで直接指定するAPIになっています。またベース・コンポーネントの実装内で指定されたpaddingやmarginなどの値はexportされていないため、オリジナルのデザイン・マナーを保ちつつカスタマイズをするのに向かない面があります。
Native Base 3.0は使って楽しいUI開発キット
そんな中で、Utility Style Propsをベースによく使われるUIコンポーネントが実装されたNative Baseは、UIライブラリとしてだけでなくそれをベースに独自のUIを構築するための「UI開発キット」としてとても魅力的だと感じました。
なにより、レイアウト系コンポーネントの設計が良く考えられていて、サクサクと自分の思い描くUIを実装できるのが楽しいですね。みなさんも、React NativeアプリケーションのUIを構築するライブラリとして、ぜひ一度試してみてください。
おまけ: U-motion開発部はテクノロジーで農家さんに貢献したいエンジニアを募集中です!!
デザミス株式会社では、JavaScript/Reactでフロントエンド開発をしたいエンジニアと、バックエンド・エンジニアを募集中です。
こちらからお気軽に問い合わせてください。面接は無しでまずはカジュアル面談から、という方も大歓迎です。
フロントエンド
・React + TypeScriptを使った大規模なアプリケーション開発
・React Nativeを使ったネイティブ・アプリケーション開発
バックエンド
・大量のデータを扱うバックエンド開発(Rails、Python、AWS)