コース目次 / 第4章
自分のものにする
同じものが続けて出ないように直して、行き先を自分のリストに置き換えます。
最後の章です。気になっていたところを1つ直して、中身を自分のものに置き換えます。
1. 同じものが続けて出ないようにする
第3章の最後に書いたとおり、いまは同じ行き先が2回続くことがあります。押した人には「壊れている」ように見えます。
直し方は単純で、いま出ているものを候補から外してから選ぶだけです。lib/roulette.ts の末尾に足します。
return spots[Math.floor(random() * spots.length)]; }++/**+ * 直前と同じものは出さずに1つ選ぶ。+ *+ * 同じ行き先が続けて出ると、押した人には「壊れている」ように見える。+ * だから、いま出ているものを候補から外してから選ぶ。+ */+export function pickNext(+ spots: Spot[],+ current: Spot | null,+ random: () => number = Math.random,+): Spot {+ const rest = spots.filter((spot) => spot.name !== current?.name);+ return pick(rest.length === 0 ? spots : rest, random);+}行頭の + - は変更の目印です。コピーすると、記号と削除された行を除いたこの章を終えた時点の内容が入ります。
filter で「いまのものだけ除いた一覧」を作り、そこから選んでいます。候補が1件しかないときは除くと0件になってしまうので、そのときだけ元の一覧から選びます。
current?.name の ?. は「current が null なら、そこで止まって undefined にする」という書き方です。まだ1回も押していないとき(current が null)でも落ちません。
つぎに App.tsx を、新しいほうを使うように変えます。
import { useState } from 'react'; import { Pressable, StyleSheet, Text, View } from 'react-native';-import { pick, SPOTS, type Spot } from './lib/roulette';+import { pickNext, SPOTS, type Spot } from './lib/roulette'; export default function App() {行頭の + - は変更の目印です。コピーすると、記号と削除された行を除いたこの章を終えた時点の内容が入ります。
</View> - <Pressable style={styles.button} onPress={() => setSpot(pick(SPOTS))}>- <Text style={styles.buttonLabel}>まわす</Text>+ <Pressable+ style={styles.button}+ onPress={() => setSpot((current) => pickNext(SPOTS, current))}+ >+ <Text style={styles.buttonLabel}>{spot === null ? 'まわす' : 'もう一度'}</Text> </Pressable>行頭の + - は変更の目印です。コピーすると、記号と削除された行を除いたこの章を終えた時点の内容が入ります。
setSpot((current) => …) という書き方に変わりました。「いまの値を受け取って、次の値を返す」形です。
こうしないと「いま何が出ているか」が分からず、除きようがありません。値を書き換えるときにいまの値が要るなら、この形と覚えておくと、この先ずっと使えます。
保存して、スマホで10回くらい連続で押してみてください。同じものが2回続けて出なくなっています。
2. あなたの番
ここからが本番です。3つとも、値を書き換えるだけです。
(1) 自分の行き先にする
lib/roulette.ts の SPOTS を、あなたの行きたい場所に書き換えてください。件数は何件でも動きます。
export const SPOTS: Spot[] = [
{ name: '台北', hint: '夜市を端から端まで' },
{ name: '釜山', hint: '海沿いの市場で朝ごはん' },
{ name: '青森', hint: 'ねぶたの時期をねらう' },
];行き先でなくてもかまいません。「今日の夕飯」「次に読む本」「掃除する場所」——一覧から1つ選ぶものなら何でも同じ形で作れます。
(2) 見た目を変える
App.tsx の下半分、StyleSheet.create の中の数字と色を変えてみてください。
| 変えるところ | 何が変わるか |
|---|---|
name の fontSize |
選ばれた行き先の文字の大きさ |
button の backgroundColor |
ボタンの色 |
container の backgroundColor |
背景の色 |
保存するたびにスマホが変わります。数字を大げさに変えたほうが、変化が分かって楽しいです。
(3) ボタンの文字を変える
まわす もう一度 の文字を、自分の言葉にしてください。
3. 持ち帰りカード
フォルダに README.md を置いておきます。3か月後のあなたが読む用です。
# 旅先ルーレット
Tsumiki のミニ体験コース「React Native — 自分のスマホで動くアプリ」の成果物です。
## また動かすとき(3行)
1. ターミナルを開いて `cd` でこのフォルダに入る
2. `npx expo start` と打つ
3. 出てきたQRを読む(iPhoneは**カメラアプリ**、Androidは**Expo Go の中**から)
パソコンとスマホが**同じWi-Fi**につながっていることが条件です。つながらないときは
`npx expo start --tunnel` にすると、別のネットワークからでも届きます。
ZIPから戻したときや、`node_modules` フォルダが無いときは、先に `npm install` を1回。
## 中身
| ファイル | 何をするか |
|---|---|
| `App.tsx` | 画面。ボタンと、選ばれた行き先の表示 |
| `lib/roulette.ts` | 行き先の一覧と、選ぶ処理。**ここだけ書き換えれば自分用になる** |
| `app.json` | アプリの名前やアイコンの設定 |
| `package.json` | 使っている部品の一覧。Expo SDK のバージョンもここ |
## 大事な決めごと
このアプリは **Expo SDK 54** で作ってあります。App Store / Google Play で配られている
Expo Go が対応しているのが SDK 54 だからです。**SDK を上げると、ストア版の Expo Go では
開けなくなることがあります。**上げるのは、Expo Go 側が追いついたと確かめてからにしてください。
## この先に進むなら
- Expo 公式ドキュメント https://docs.expo.dev/
- React Native の部品カタログ https://reactnative.dev/docs/components-and-apis
- 画面を増やしたくなったら Expo Router。ストアに出したくなったら EAS Build。
どちらもこのコースでは扱いませんでしたこのアプリは「あなたのスマホの Expo Go から開けるもの」であって、ホーム画面に置けるアプリではありません。ホーム画面のアイコンにしたり、ストアに出したりするには、EAS Build という別の仕組みが要ります(Apple の年会費も要ります)。このコースでは扱いませんでした。
とはいえ、手元のパソコンには本物のソースコードが残っています。そこから先へ進む道は、いつでも開いています。
この教材は、いちばん早く古くなります
正直に書いておきます。8本の試食コーナーの中で、この教材はいちばん腐りやすいです。
Expo は年に数回SDKを更新します。そのたびに、ストア版の Expo Go が対応するSDKも(遅れて)変わります。このページの @sdk-54 という数字は、いつか古くなります。
だから、しばらく経ってから作り直すときは、まず Expo Go が対応しているSDKを確かめてください。確かめ方はかんたんで、Snack を開いて、下の帯のバージョン欄が既定で何番になっているかを見るだけです。Snack の既定は、だいたいストア版 Expo Go に合わせてあります。
試食レポート
おつかれさまでした。手元には自分のスマホで動くアプリと、そのソースコードが残りました。
React Native は「Webの書き味のまま、本物のスマホアプリを作る」ための道具です。今日やったのはその入口ですが、画面を作って、状態を持って、タップに反応するという骨格は、大きなアプリでもまったく同じです。
この道具、合いそうでしたか?
CSSが効かないところ、スマホとパソコンを行き来する手間、そのかわりに得られる「手に持ったものが動く」という手応え。合いそうなら、Expo公式ドキュメントとReact Native の部品カタログが次の一歩です。
ぴんと来なかったなら、それも収穫です。別の言語を試食してみてください。
ハマったら
ZIPで戻したい
このページの下のZIPは、この章を終えた状態のフォルダです。解凍して、その中で作業を続けられます。自分で書き換えた部分は消えてしまうので、先に自分のファイルを別の場所へ待避してから使ってください。
こうなっていればOK
うまくいかないときは、この章の完成ファイル一式(ZIP)をダウンロードして続きから進めても大丈夫です。
この章で卒業です。
この章はまだ完了していません。
保存できませんでした(プライベートブラウズ中かもしれません)。この端末に進捗は残りませんが、先へは進めます。