ExpoとNativeWindで高品質なUIを構築する
開発 • React Native • 2026年2月3日 • 3分で読める
Thomino ゲスト著者
Expo、NativeWind、Reanimatedを使用してReact Nativeアプリを直接コードでデザインする方法を学びます。再利用可能なコンポーネントを構築し、テーマを実装し、Figmaをスキップしましょう。
これはThominoからのゲスト投稿です - 彼はNative Templatesの作成者であり、Xでフォローする価値のある人物です。
私はIE6の時代からWebを構築してきました。ボックスシャドウにスライスした画像を使用し、角丸に透明GIFを使用し、構造に入れ子のテーブルを使用していたことを覚えています。それらはフロントエンド開発の「暗黒時代」でした。
幸い、時代は変わりました。Expo、NativeWind、Reanimatedの組み合わせにより、アプリのデザインは簡単になりました。実際、私はもうFigmaを使用していません。Expo Goのライブプレビューでコード内で直接デザインしています。
私のワークフローで使用する再利用可能なコンポーネントを使って、どのようにアプリを構築するかをお見せしましょう。これらのコンポーネントにより、エディタで直接デザインできます。また、テーマの処理方法とアニメーション付きテーマトグルの構築方法についても説明します。
再利用可能なコンポーネント
各アプリは異なりますが、ほとんどのアプリは多くの画面、フロー、コンポーネントを共有しています。そのため、私のニーズに応じて新しいプロジェクトのベースとして常に使用できるテンプレートを構築することにしました。
これを効果的に行うための鍵は、特定のアプリに応じて簡単にスタイリングできる再利用可能なコンポーネントを作成することでした。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;
<Header title="Home" />
<Header title="Details" showBackButton />
<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でアニメーション付きダークモードトグルを構築する