コンテンツにスキップ
Webフロントエンドエンジニアのための React Native 実践入門
Esc
navigateopen⌘Jpreview
このページの内容

第3章 ReactとReact Nativeの違いと共通点

コンポーネント指向やHooksがそのまま通用する一方で、DOM・CSS・ブラウザAPIがない環境で何を学び直すことになるかがつかめます。

React開発の経験があるエンジニアにとって、React Nativeへの入り口で気になるのは「どこまでが同じで、どこからが違うのか」という点だと思います。本章では両者の差分を整理し、Webの知識がそのまま使える領域と、学び直しが必要な領域を分けて見ていきます。

共通する考え方

まず、Reactで身につけた発想のほとんどはそのまま通用します。

コンポーネント指向

UIを関数コンポーネントに分割し、propsで値を渡し、必要に応じてstateを持たせる、という基本構造は同じです。

type GreetingProps = {
  name: string;
};

function Greeting({ name }: GreetingProps) {
  return <Text>こんにちは、{name}さん</Text>;
}

返すのが<div><View>かの違いはありますが、設計の発想は変わりません。

Hooks

useStateuseEffectuseMemouseCallbackuseReduceruseContext、カスタムフック ― これらはすべてReact Nativeでも同じように使えます。React 19で追加されたuseuseActionStateuseOptimistic、React 19.2のuseEffectEventなども同様です。

「Hooksの使い方をWeb側で身につけている」というだけで、React Native側の学習はかなり省けます。

状態管理ライブラリ

Zustand、Jotai、Redux Toolkitなど、Web側で使われている状態管理ライブラリは、おおむねReact Nativeでもそのまま動きます。Reactのコンポーネントツリーに対して動くライブラリであれば、ランタイムが違ってもインターフェースは同じだからです。

データフェッチ

TanStack QueryやSWRといったデータフェッチライブラリも、そのまま使えます。fetch APIもReact Nativeに標準で用意されています(厳密にはWebのfetchと完全に同じではないものの、基本的な使い方の範囲では差を意識せずに済みます)。

TypeScript

型定義の書き方、tsconfigの方針、ESLintの考え方、Prettierの使い方など、コードの書き心地に関する部分はWebとほぼ変わりません。

決定的に違う点

ここからが「学び直し」が必要な領域です。

DOMがない

最大の違いはこれです。

React NativeにはDOMがありません。document.getElementByIddocument.createElementも存在しません。windowオブジェクトも、ブラウザに紐づく機能(window.locationwindow.historywindow.scrollYなど)はそもそも提供されません。

DOMを直接触るタイプのライブラリは、まず動きません。<div>を直接書くこともできず、代わりに<View><Text><Image><TextInput><ScrollView><FlatList>といったReact Nativeのコアコンポーネントを使います。

Web React Native
<div> <View>
<span> <p> <Text>
<img> <Image>
<input type="text"> <textarea> <TextInput>
<button> <Pressable>
<a> <Link> (Expo Router)
スクロール領域(overflow: auto) <ScrollView>
大量リスト(<ul> + map) <FlatList>
ノッチを避ける外枠 <SafeAreaView>
切り替えコントロール(<input type="checkbox">の見た目違い) <Switch>
ローディング表示 <ActivityIndicator>
アラート/確認ダイアログ Alert.alert()

React Nativeのコアコンポーネントは「意外と少ない」のが特徴で、上記がほぼすべてです。残りはExpo Modulesやサードパーティライブラリで補います。

たとえば、同じ「アバター画像とユーザー名のカード」をWebとReact Nativeで書き比べると、こんな対応関係になります。

// Web (React)
function ProfileCard() {
  return (
    <div className="card">
      <img src="/avatar.png" className="avatar" />
      <p className="name">kazutoyo</p>
    </div>
  );
}
// React Native
function ProfileCard() {
  return (
    <View style={styles.card}>
      <Image source={{ uri: "/avatar.png" }} style={styles.avatar} />
      <Text style={styles.name}>kazutoyo</Text>
    </View>
  );
}

タグ名とstyleの与え方が変わるだけで、JSXの構造はそのままです。詳しい使い方は第6章で扱います。

CSSが使えない

stylesheetやCSS-in-JSライブラリ(CSSベースのもの)、Tailwindの素のクラスなどは、そのままでは動きません。代わりに、JavaScriptオブジェクトとしてスタイルを書くStyleSheet APIを使います。

import { StyleSheet, View, Text } from "react-native";

function Card() {
  return (
    <View style={styles.card}>
      <Text style={styles.title}>タイトル</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  card: {
    padding: 16,
    borderRadius: 8,
    backgroundColor: "#fff",
  },
  title: {
    fontSize: 18,
    fontWeight: "bold",
  },
});

書き方が違うだけで、考え方はWebのスタイル指定と地続きです。プロパティ名はキャメルケースになり、値は文字列("#fff")か数値(16)で指定します。

ただし、使えるプロパティは「CSSのサブセット」と思っておくのが安全です。grid-template-columnsは今のところ使えません(2026年に向けて、React NativeのレイアウトエンジンYogaへCSS Grid追加が議論されています)。background-imageもありません(画像は<Image>コンポーネントで配置するか、サードパーティのライブラリでサポートされています)。

Tailwindライクなスタイリングが好みであれば、Uniwindという選択肢があります。詳しくは第7章で扱います。

ブラウザAPIがない

localStoragesessionStorageIndexedDBdocument.cookienavigator.geolocationnavigator.mediaDevicesNotificationWeb Speech APIService Worker ― これらブラウザに紐づくAPIは、React Nativeには存在しません。

代替として、それぞれの機能はExpoのモジュールが提供しています。

Web React Native (Expo)
localStorage AsyncStorage / MMKV
navigator.geolocation expo-location
navigator.mediaDevices expo-camera / expo-image-picker
Notification expo-notifications
URLルーティング Expo Router

「Webにあるあの機能、モバイルでは何を使う?」という対応関係を覚えていけば、徐々に脳内のマッピングが揃っていきます。

Flexboxのデフォルトが違う

Webではdisplay: flexを指定しなければflexになりませんし、flexにした場合のデフォルトはflex-direction: rowです。

Web CSSとReact Nativeで異なるFlexboxのデフォルト方向と、flexDirection rowで横並びにする関係

React Nativeでは次のようになっています。

  • すべての<View>は最初からdisplay: flex相当(displayflex/none/contentsの3値のみでWebほど種類はありません)
  • flex-directionのデフォルトは**column**(縦並び)

これは「縦スクロールが基本のモバイル画面」という前提に最適化された結果です。Webの感覚で組むと「あれ、横に並ばない…」と最初に戸惑うポイントですが、慣れてしまえば縦が基本なほうが楽な場面が多いです。align-itemsのデフォルトがstretchなのはWebと同じです。

横並びにしたい時だけflexDirection: "row"を明示します。

単位が違う(pxではなくdp)

CSSではピクセル単位(px)、emやrem、vw/vhなどさまざまな単位がありますが、React Nativeではスタイルの数値はすべて**dp(密度非依存ピクセル)**として扱われます。単位を書く必要すらありません。

// Web
const style = { padding: "16px", fontSize: "18px" };

// React Native
const style = { padding: 16, fontSize: 18 };

dpはOSが画面密度に応じて実ピクセルに変換してくれるので、解像度の違うデバイスでも見た目のサイズが揃います。

スクロールの扱いが違う

Webでoverflow: autoを指定すれば自動でスクロールしましたが、React Nativeではスクロールしたい領域は明示的に<ScrollView>または<FlatList>で囲む必要があります。

リストが大量になる場面では、仮想化されている<FlatList>を使うのが定番です。Webの<div>に大量の<li>を入れてoverflow: auto、というやり方は、モバイルではメモリやパフォーマンスの観点で破綻するので、最初から仮想化を意識します。

詳しくは第6章で扱います。

(コラム) Webのコンポーネントをそのまま持ち込む ― DOM Components

ここまで「DOMがない」「CSSが使えない」と書いてきましたが、逃げ道もあります。ExpoのDOM Componentsです。

ファイルの先頭に'use dom'と書くと、そのコンポーネントだけがReact DOMとして扱われ、WebView上で描画されます。

// components/rich-editor.tsx
'use dom';

export default function RichEditor() {
  // ここでは <div> も CSS も、Web向けライブラリもそのまま使える
  return <div style={{ padding: 16 }}>Webの世界</div>;
}

呼び出す側は、普通のコンポーネントとしてimportするだけです。Expo SDK 56以降は@expo/dom-webviewが既定で使われるので追加インストールは不要で、SDK 55以前ではreact-native-webviewを入れておきます。

効いてくるのは、リッチテキストエディタやチャートのように「Web向けの資産をそのまま使いたい」場面です。既存のWebサイトをアプリ化したい場合にも、コンポーネント単位で少しずつネイティブへ移していく、という進め方ができます。

ただし中身はWebViewなので、ネイティブUIではありません。スクロールの感触やパフォーマンスはネイティブの部品に劣りますし、多用すれば結局「WebViewアプリ」に近づいてしまいます。アプリの骨格はコアコンポーネントで組み、どうしてもWeb資産を使いたい部分にだけ差し込む ― という距離感で付き合うのが良いと思います。

実際に組み込んでみた手順と使い勝手はExpoのReact DOM componentsでReact NativeにReact(Web)を組み込むに書いています。

知識マップ ― そのまま使える領域 / 学び直しの領域

領域 そのまま使える 学び直しが必要
コンポーネント設計
Hooks
TypeScript
状態管理ライブラリ
データフェッチ(TanStack Query等)
マークアップタグ コアコンポーネント
スタイリング StyleSheet API / Uniwind
ルーティング Expo Router
永続化 AsyncStorage / MMKV
メディア・センサー Expo Modules各種
レイアウトの直感(Flex方向、単位) dp、column起点に頭を切り替え

「学び直し」と書きましたが、内容自体は数日でなじむレベルです。「Webと違う部分」だけにフォーカスして学習リソースを当てれば、思っているより早く立ち上がれます。

本章のまとめ

  • Reactで身につけた発想(コンポーネント、Hooks、状態管理、データフェッチ)はそのまま使える
  • DOM、CSS、ブラウザAPIといったWeb固有の道具は使えない
  • 代わりにコアコンポーネント、StyleSheet API、Expo Modules、Expo Routerが対応する
  • レイアウトはflex columnが起点、単位はdp、スクロールは明示的

次章からは、本書で前提とする開発フレームワークExpoについて見ていきます。

最終更新 2026年7月24日