Expo と NativeWind で高品質な UI を構築する
開発 • React Native • 2026-02-03 • 読了時間: 3分
Thomino(ゲスト著者)
Expo、NativeWind、Reanimated を使ってコード上で直接 React Native アプリをデザインする方法を学びます。再利用可能なコンポーネントを構築し、テーマを実装し、Figma を使わずに済ませる方法を紹介します。
この記事は Thomino の寄稿です。彼は Native Templates の作者で、X でフォローすると良いアカウントです。
私は IE6 の時代からウェブを作ってきました。ボックスシャドウにスライス画像を使い、角丸に透明 GIF を使い、構造にネストしたテーブルを使っていたことを覚えています。あれはフロントエンド開発の「暗黒時代」でした。幸い状況は変わりました。Expo、NativeWind、Reanimated の組み合わせがあれば、アプリのデザインは非常に簡単です。実際、私はもう Figma を使っていません。Expo Go のライブプレビューで直接コード内でデザインしています。
以下では、私がワークフローで使っている再利用可能なコンポーネントでどのようにアプリを作っているかを紹介します。これらのコンポーネントによってエディタ内で直接デザインできます。さらに、テーマの扱い方とアニメーション付きのテーマ切替(Theme toggle)の作り方も解説します。
再利用可能なコンポーネント
各アプリは異なりますが、多くは画面、フロー、コンポーネントを共有します。そのため、新しいプロジェクトでベースとして常に使えるテンプレートを作ることにしました。効果的に行う鍵は、特定のアプリに合わせて簡単にスタイル調整できる再利用可能なコンポーネントを作ることでした。以下は私が NativeTemplates で実装したいくつかの例です。
NativeWind で柔軟なヘッダーコンポーネントを作る
おそらく最も重要で基本的なコンポーネントです。ヘッダーを柔軟で調整しやすくすることが非常に重要でした。
コード例:
import React from "react" ;
import { View , Text , TouchableOpacity } from "react-native" ;
import { useThemeColors } from "app/contexts/ThemeColors" ;
import { Link , router } from "expo-router" ;
import Icon , { IconName } from "./Icon" ;
import { useSafeAreaInsets } from "react-native-safe-area-context" ;
type HeaderProps = { title : string , showBackButton ? : boolean , rightComponents ? : React . ReactNode [ ] , } ;
const Header : React . FC < HeaderProps > = ( { title , showBackButton = false , rightComponents = [ ] , } ) => { const colors = useThemeColors ( ) ; const insets = useSafeAreaInsets ( ) ; const handleBackPress = ( ) => { router . back ( ) ; } ; return ( < View style = { { paddingTop : insets . top } } className = "w-full pb-2 flex-row justify-between px-6 bg-background" > < View className = "flex-row items-center flex-1" > { showBackButton && ( < TouchableOpacity onPress = { handleBackPress } className = "mr-4 py-4" > < Icon name = "ArrowLeft" size = { 24 } color = { colors . icon } / > < / TouchableOpacity > ) } < View className = "py-4" > < Text className = "text-lg font-bold" style = { { color : colors . text } } > { title } < / Text > < / View > < / View > { rightComponents . length > 0 && ( < View className = "flex-row items-center justify-end flex-1" > { rightComponents . map ( ( component , index ) => ( < View key = { index } className = "ml-6" > { component } < / View > ) ) } < / View > ) } < / View > ) ; } ; export default Header ;
使用例:
// Basic header with title < Header title = "Home" / >
// Header with back button < Header title = "Details" showBackButton / >
// Header with action icons < Header title = "Messages" rightComponents = { [ < HeaderIcon key = "search" icon = "Search" href = "/search" / > , < HeaderIcon key = "settings" icon = "Settings" href = "/settings" / > ] } / >
React Native でアニメーション付きタブナビゲーションを作成
アイコン、アニメーション、またはアバターを選べます。
コード例:
< TabTrigger name = "home" href = "/" asChild >
< TabButton labelAnimated = { true } icon = "Home" > Home < / TabButton >
< / TabTrigger >
< TabTrigger name = "profile" href = "/profile" asChild >
< TabButton labelAnimated = { true } avatar = { require ( '@/assets/img/thomino.jpg' ) } > Profile < / TabButton >
< / TabTrigger >
マルチステップフォームとオンボーディングフローの構築
これは非常によく使います。オンボーディングやその他のユーザーフローに最適です。オンボーディングはユーザーを活性化し、早期離脱を減らすのに不可欠です。
コード例:
< MultiStep onComplete = { handleComplete } onClose = { handleClose } headerTitle = "Get Started" >
< Step title = "Profile" >
< Profile / >
< / Step >
< Step title = "Role" >
< Role / >
< / Step >
< Step title = "Capabilities" >
< Capabilities / >
< / Step >
< Step title = "Review" >
< Review / >
< / Step >
< / MultiStep >
フィルターやフォーム向けの再利用可能なチップコンポーネント
これは非常に基本的ですが、フィルターやフォームで多用します。
コード例:
< Chip label = "Custom" className = "my-2 mx-1" size = "xl" / >
ドキュメントで全コンポーネントを確認できます。
NativeWind でテーマ変数を実装する
NativeWind によってテーマ化が非常に強力になります。vars を使うことで、アプリ全体のテーマを1ファイルで切り替えられます。これにより、ライト/ダークモードが単なる後付けではなく、デザインシステムの中核になります。
コード例:
import { vars } from "nativewind" ;
export const themes = { light : vars ( { "--color-primary" : "#000000" , "--color-invert" : "#ffffff" , "--color-secondary" : "#ffffff" , "--color-background" : "#F4F4F5" , "--color-darker" : "#F4F4F5" , "--color-text" : "#000000" , "--color-highlight" : "#7E55D8" , "--color-border" : "rgba(0, 0, 0, 0.15)" , } ) , dark : vars ( { "--color-primary" : "#ffffff" , "--color-invert" : "#000000" , "--color-secondary" : "#1e1e1e" , "--color-background" : "#141414" , "--color-darker" : "#000000" , "--color-text" : "#ffffff" , "--color-highlight" : "#7E55D8" , "--color-border" : "rgba(255, 255, 255, 0.15)" , } ) , } ;
Reanimated でアニメーションするダークモード切替を作る
Reanimated を使ってテーマ切替をアニメーション化します。ユーザーがテーマを切り替えたときに滑らかなトランジションやインタラクティブなフィードバックを追加することで、体験を向上させます。