前回はReact Nativeの始め方についての記事を書きました。

今回は実際にコードを書くところの記事です。
React Nativeのコードを開いて、最初に思ったのは「読めない」でした。
div も p も span も出てきません。
className もありません。
HTMLとCSSは多少触ってきたつもりだったのに、それがほとんど通用しない画面がそこにありました。
AIに書いてもらったコードを自分で直そうとしても、どこが何なのか分からないので手が止まります。
なので今回は、HTMLのタグがReact Nativeで何に置き換わるのかという対応関係から整理しました。
そもそもHTMLのタグは1つも使えない
まずここが大前提でした。
React Nativeは、最終的にiPhoneやAndroidの本物の部品を動かします。
ブラウザで動いているわけではないので、ブラウザ用のタグであるHTMLは出番がありません。
代わりに使うのが、React Nativeが用意しているコンポーネントです。
View や Text といった名前で、頭文字が大文字なのが目印です。
そしてもう1つ、Webと違うところがあります。
使うコンポーネントは、ファイルの一番上で毎回importします。
import { View, Text } from 'react-native';
HTMLでは <div> をいきなり書けたので、この工程が最初は抜けました。
importを書き忘れると「そんな名前は定義されていない」という趣旨のエラーになります。
コードを追加したのに動かないとき、私はまずここを見るようにしています。
HTMLとの対応表
よく使うものだけ並べました。
| HTML | React Native | メモ |
|---|---|---|
| div | View | 一番よく使う箱 |
| p / span | Text | 文字は必ずこれで包む |
| img | Image | サイズの指定が必要なことが多い |
| input | TextInput | 入力欄 |
| button | Pressable | ほかにも選択肢がある(後述) |
| ul / li | FlatList | ViewとTextの繰り返しでも書ける |
| a href | Link | Expo Routerのもの |
| (スクロール) | ScrollView | HTMLは勝手にスクロールするが、こちらは指定する |
| (該当なし) | SafeAreaView | ノッチやホームバーを避けるための枠 |
この表で個人的に大きかったのは、スクロールが自動ではないという点でした。
Webでは中身が画面をはみ出せば勝手にスクロールしますが、React Nativeでは ScrollView で囲まないと、はみ出した部分は見られないままになります。
「下の方が切れている」と思ったら囲み忘れ、というパターンがありそうです。
最初にひっかかるルール
文字は必ずTextで包む
これは実際にエラーを出しました。
// これはエラーになる
<View>
こんにちは
</View>
// これが正しい
<View>
<Text>こんにちは</Text>
</View>
HTMLでは <div>こんにちは</div> がそのまま通るので、ここは感覚が違いました。
文字を画面に出すときは、例外なくTextで包みます。
ボタンの中の文字も、リストの項目の文字も同じです。
逆に言うと、Text が出てこないコードには文字が表示されていない、という読み方もできるようになります。
見出しタグが存在しない
h1 から h6 にあたるものがありません。
大きい文字を出したいときも、使うのは Text です。
そのうえで文字サイズを自分で指定します。
HTMLは h1 と書けばブラウザが勝手に大きくしてくれましたが、React Nativeには最初から付いてくる見た目がほとんどありません。
太さも大きさも余白も、全部自分で書くことになります。
最初にコードを見たとき、やたらスタイルの指定が多いなと思ったのですが、理由はここでした。
onClickではなくonPress
タップされたときの処理は onPress で書きます。
<Pressable onPress={handlePress}>
<Text>押す</Text>
</Pressable>
指で押すものなので click ではなく press、という理解でいます。
onClick と書いてもエラーにはならず、ただ何も起きません。
調べた範囲では、これは「知らない属性を書いただけ」の扱いになるからのようです。
エラーが出ないぶん原因に気づきにくいので、押しても反応しないときは onPress になっているかを先に見るようにしています。
ボタンの部品が複数あって迷った
押せるものを作りたいだけなのに、候補がいくつも出てきます。
調べた範囲では、こういう整理でした。
| 名前 | 立ち位置 |
|---|---|
| Pressable | 公式が今すすめているもの。見た目を自由に作れる |
| Button | すぐ置けるが、色くらいしか変えられない |
| TouchableOpacity | 動くが、公式ドキュメントはPressableを案内している |
| TouchableHighlight など | 特別な理由がなければ使わない |
React Nativeの公式ドキュメントでは、TouchableOpacityのページ自体に「今後を見据えるならPressableを見てほしい」という趣旨の案内が出ています。
ただ、ネット上の解説記事にはTouchableOpacityがまだ多く残っています。
AIに書いてもらったコードでも出てくることがあります。
動かないわけではないので慌てる必要はないのですが、新しく書くならPressableに寄せておくほうが良さそうだと思いました。
Button は見た目をほぼ変えられないので、動作確認の仮置きに向いているという理解です。
リストを出すときの選択肢
ul と li にあたるものは、決まった1つのタグではありませんでした。
単純に繰り返すだけなら、View と Text を並べる書き方でも出せます。
ただ、React Nativeには FlatList という専用の部品が用意されています。
調べた範囲では、両者の違いは「画面に見えている分だけ描くかどうか」でした。
普通に並べる書き方だと、項目が1000件あれば1000件ぶん全部作ってから表示します。
FlatList は見えている範囲だけを作って、スクロールに合わせて差し替えていきます。
件数が増えるほど動きの軽さに差が出るようです。
項目が数個しかない画面なら普通に並べて、件数が増えていく画面ではFlatList、という使い分けで理解しています。
ちなみに ScrollView も中身を全部先に作るタイプなので、長いリストには向かないとされています。
画面を移動するリンク
<a href="..."> にあたるものもありません。
Expo Routerを使っている構成では、こう書きます。
import { Link } from 'expo-router';
<Link href="/sample">
<Text>サンプル画面へ</Text>
</Link>
href に書くのはファイル名です。
準備編で書いたとおり、Expo Routerはファイル名がそのまま画面のURLになる仕組みなので、sample.tsx があれば /sample で飛べます。
アプリの外、たとえばブラウザでWebサイトを開きたい場合は、Linking という別の機能を使うようです。ここはまだ自分では書いていません。
短いコードを読んでみる
ここまでを踏まえて、一番シンプルな画面のコードを見ておきます。
import { StyleSheet, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
export default function SampleScreen() {
return (
<SafeAreaView style={styles.container}>
<View style={styles.inner}>
<Text style={styles.title}>サンプル</Text>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: { flex: 1 },
inner: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
title: {
fontSize: 24,
fontWeight: '600',
},
});
上から順に読むと、こうなります。
1行目と2行目で、使う部品をimportしています。SafeAreaView だけ別のところから来ているのは、これがReact Native本体ではなく追加のライブラリの部品だからです。
export default function の行が、この画面そのものの宣言です。
return の中が、画面に出る中身です。ノッチを避ける枠があって、その中に箱があって、その中に文字がある、という入れ子になっています。
そして一番下の StyleSheet.create が、CSSにあたる部分です。
同じファイルの中に見た目の指定が書かれているのが、Webとの一番大きな違いだと思いました。
CSSファイルを探しても見つからないわけです。
このスタイルの書き方については、次の記事でまとめます。

まとめ
整理してみると、覚えることはそれほど多くありませんでした。
箱は View、文字は Text、押すものは Pressable。
文字は必ず Text で包んで、タップの処理は onPress。
使う部品は毎回importする。
この5つを頭に入れてからコードを見返したら、何も分からなかった画面が、何をしているかは追える画面に変わりました。
直せるかどうかはまた別の話ですが、少なくとも「どこを触ればいいか」の見当は付くようになっています。
次は、その見た目の指定をどこに書くのかという話に進みます。
ここまで読んでくださりありがとうございました。
この記事のカテゴリー
開発ブログ の記事をもっと見る →