React実践の導入スライド
型が無いと止まらない
型を書かないと、props の名前を打ち間違えても実行するまで気づけません。
型を書かない
function ItemCard(props) {
return <p>{props.titel}</p>;
}型を書く
function ItemCard(
props: ItemCardProps
) {
return <p>{props.titel}</p>;
}右はこの打ち間違いに、書いているその場で気づけます。
1 / 5
React実践 - propsに型を付ける
型の口に何が届くか
渡す側の書き方を切り替えて、型の口に何が届くか確かめてください。
- 2つ渡すと、title と price の両方が型どおりに届く
- price を忘れると、その口が空のまま止まる
- price を文字で渡すと、型が違うとして止まる
2 / 5
分割代入で受け取る
引数のところで、型を付けたまま分割代入して受け取ります。props. をくり返さずに item だけで扱えます。
{ item }分割代入で受け取る: ItemCardProps型を付ける3 / 5
商品の型を切り出す
商品の形は複数の場所で使うので、型を独立させておきます。
項目を個別に渡す
type ItemCardProps = {
title: string;
price: number;
};商品ごと渡す
type ItemCardProps = {
item: Item;
};商品の項目が増えても、渡す側は書きかえずに済みます。
4 / 5
考えてみよう外しても進めます
商品の型を Item として独立させておく理由は何ですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
初期値があるか、ないか
最初に何を入れるかで、TypeScript が型を決められるかが変わります。
初期値が空のまま
const [items, setItems] =
useState([]);
// items は never[] になる山かっこで型を渡す
const [items, setItems] =
useState<Item[]>([]);
// items は Item[] になる空配列からは中身の型が分からないので、自分で教えます。
1 / 5
React実践 - useStateの型
上下で入るか試す
取ってきた商品の件数を動かして、上と下のどちらに入るか見くらべてください。
- 件数を増やすと、型を書いた上の段には入り、書かない下の段は弾かれる
- 件数を0にすると下も通る。空のうちは差が出ない
- 型を書いた側だけ、件数がいくつでも止まらない
2 / 5
止まる場所を先に見る
もう1つ、まだ選ばれていない状態にも型が要ります。
選択中の商品に型を書かずに中身を読む
何も選ばれていないときに実行時エラーで画面が壊れる
まだ無い状態を型で表さないまま進める
詳細画面を開くたびに同じ場所で落ちる
型に null を含めておくと、この事故をコード側で止められます。
3 / 5
2件の商品を型で持つ
items に型を付けて、2件の商品をそのまま初期値にします。
useState<Item[]>山かっこで型を渡す結果
| id | title | price |
|---|---|---|
| 1 | スニーカー | 4800 |
| 2 | 革靴 | 9800 |
4 / 5
考えてみよう外しても進めます
選択中の商品の型に null を含めておくと、TypeScript は何をしてくれますか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
型が無い引数、ある引数
e の型が無いと、TypeScript は e の中身に何があるか判断できません。
型を書かない
function handleChange(e) {
setKeyword(e.target.value);
}イベントの型を書く
function handleChange(
e: ChangeEvent<HTMLInputElement>
) {
setKeyword(e.target.value);
}山かっこの中が、そのまま e.target の正体になります。
1 / 5
React実践 - イベントの型
eの中身を切り替える
引数 e に書く型を切り替えて、e.target の中身がどう変わるか見てください。
- 入力欄を選ぶと、e.target から value が文字として読める
- フォームを選ぶと、value という項目自体が無いと言われる
- any を選ぶと型を確かめないので、打ち間違えても止まらない
2 / 5
つまずきやすい2つ
型を書くとき、この2つはよく引っかかります。
型だけの import に type を付けない
消えるはずの行が、実行するコードとして残る
使わない引数にまで型を書く
読む行が増えるだけで、得るものが無い
import の中で type を付けておくと、消えるものだとはっきりします。
3 / 5
打った文字を渡す
打った文字がそのまま e.target.value で読めるので、表示用の state にすぐ渡せます。
ChangeEvent<HTMLInputElement>入力欄のイベント型結果
| 入力した文字 | 画面の表示 |
|---|---|
| スニーカー | スニーカー で検索中 |
| 革靴 | 革靴 で検索中 |
4 / 5
考えてみよう外しても進めます
引数を受け取らずに呼ぶだけのボタンにも、イベントの型は必要ですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
childrenにも型がいる
title だけ受け取っていた型に、はさんだ中身を受け取る children を足します。
titleだけの型
type CardProps = {
title: string;
};childrenを足した型
type CardProps = {
title: string;
children: ReactNode;
};children という名前は決まっています。足すのは型のほうです。
1 / 5
React実践 - childrenの型
はさむものを変える
はさむものを変えて、上と下のどちらが受け取れるか確かめてください。
- JSX をはさむと、上の ReactNode の段だけ通り、下の段は弾かれる
- 文字をはさむと、上下どちらの段も受け取れる
- オブジェクトをはさむと、上下とも弾かれる
2 / 5
型を書くときの事故
ReactNode の代わりに近い型を書くと、通りすぎたり狭すぎたりします。
children を any にする
画面に出せない値まで通り、間違いに気づけない
children を JSX.Element にする
文字や配列を渡すと型エラーになる
title だけ書いて children を足し忘れる
はさんで呼ぶと、渡す側が型エラーになる
ReactNode は広く通し、any は広すぎ、JSX.Element は狭すぎます。
3 / 5
Cardが描画される
children に型を足した Card に、価格の行をはさんで呼び出した結果です。
スニーカー
4800 円
4 / 5
考えてみよう外しても進めます
Card の型に children を足します。正しい書き方はどれですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
商品はどこに置くか
第1章は配列に商品を直接書きました。本物のアプリでは、仕様書に沿って外から届きます。
配列に直接書く
const items = [
{ id: "1", title: "スニーカー" },
{ id: "2", title: "革靴" },
];仕様書から届く
{
"method": "GET",
"path": "/api/items"
}何万件あっても、書きかえるのはコードではなく仕様書のほうです。
1 / 5
React実践 - モックAPIの世界
仕様書の5つの欄
仕様書の1件には、この5つの情報が入っています。
この5つを読めれば、どんな仕様書でも同じように読めます。
| 欄 | 意味 |
|---|---|
| method | 呼ぶ動詞。取得なら GET、作成なら POST |
| path | 呼ぶ URL。途中に変わる場所を含むこともある |
| collection | 返ってくる元データの名前 |
| filters | 絞り込みに使える条件の一覧 |
| delayMs | 応答までの待ち時間 |
2 / 5
React実践 - モックAPIの世界
本物にも差し替えられる
つなぎ先と呼ぶパスを替えて、呼ぶ側の2行がどう変わるか確かめてください。
- モックから本物のサーバーに替えても、変わるのはつなぎ先だけ
- 呼ぶパスを絞り込みにすると、返ってくる件数が変わる
- 1件を選ぶと、番号のところが実際の値に置きかわる
3 / 5
仕様書の読み違い
仕様書を写すときに、ここでよくつまずきます。
GET と POST を取り違えて写す
出品のつもりが、一覧を取得するだけの入口になる
パスの中の変わる場所をそのまま残す
実際の番号に置きかえないと1件を取得できない
返ってくる元データの名前を読み飛ばす
何が返ってくる入口か説明できなくなる
仕様書は method と path と返るものを、いつも組で読みます。
4 / 5
考えてみよう外しても進めます
仕様書にある POST /api/items の入口は何をしますか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
部品はasyncにできない
部品は JSX を返すものです。実践JavaScript の書き方を、そのまま部品には付けられません。
部品をasyncにする
export default
async function App() {
const res = await fetch("...");
}中にasync関数を作る
export default function App() {
async function loadItems() {
// ここで await を使う
}
}async を付けると必ず Promise を返すので、JSX を返せなくなります。
1 / 5
React実践 - fetchとasyncの復習
awaitが止める場所
1行ずつ実行して、どの行で時間が動くか確かめてください。
- 待っているのは関数の中だけで、外の帯は止まらない
- 取ってくる行と読み取る行の2回、時間が動く
- 見つからない id を探すと、途中で止まる
2 / 5
2つのawaitを書く
返事を待ち、その中身を読み終わるまでもう一度待ちます。
await fetch1回目の待ちawait res.json()2回目の待ち結果
| 書き方 | 画面に出るもの |
|---|---|
| 取ってくる行だけ待つ | 長さが読めない |
| 両方待つ | 5 件 / 先頭は スニーカー |
3 / 5
書き忘れると
この2つが典型的な間違いです。
読み取る行の await を忘れる
中身が入る前の状態のままで、件数が読めない
async を部品の関数まで付ける
部品全体が待つものになり、JSX を返せなくなる
エラーの多くは、このどちらかが原因です。
4 / 5
考えてみよう外しても進めます
React の部品そのものに async を付けられないのはなぜですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
呼ぶ場所で結果が変わる
取得する処理を、どこに書くかで動き方がまったく変わります。
部品の中で直接呼ぶ
function App() {
loadItems();
return <div>...</div>;
}useEffectの中で呼ぶ
function App() {
useEffect(() => {
loadItems();
}, []);
return <div>...</div>;
}直接呼ぶと、取得で state が変わるたびにまた呼ばれ、止まらない輪になります。
1 / 5
React実践 - useEffectで初回取得
取得を1歩ずつ
1歩ずつ進めて、画面に何件並ぶか確かめてください。
- 最後まで進めると、0件だったところにカードが並ぶ
- 依存配列を外して最後まで進めると、左に輪ができて赤く光る
- 配列があるときは初回だけ、外すと毎回動くとラベルが変わる
2 / 5
asyncの付け方
useEffect に渡す関数そのものを async にはできません。
effect自体をasyncにする
useEffect(async () => {
const res = await fetch(url);
}, []);中でasync関数を呼ぶ
useEffect(() => {
async function load() {
const res = await fetch(url);
}
load();
}, []);async を直接付けると必ず Promise を返し、React が後片付けの関数だと勘違いします。
3 / 5
取れるまでは空
仕様書の待ち時間ぶん、最初のわずかな間は items が空の配列のままです。
経過
| 経過時間 | items |
|---|---|
| 0ミリ秒 | 空の配列 |
| 300ミリ秒 | 5件のカード |
4 / 5
考えてみよう外しても進めます
画面が出た直後、items が空の配列なのはなぜですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
anyという穴
読み取った中身は any です。何を渡しても TypeScript は黙って通します。
そのまま受け取る
const data = await res.json();
setItems(data);
// data の型は any型のある関数で受け取る
const list = await fetchItems();
setItems(list);
// list の型は Item[]any のままだと、打ち間違えても実行するまで気づけません。
1 / 5
React実践 - レスポンスに型を付ける
受け取り方を変える
受け取り方と項目名を切り替えて、どこで気づけるか確かめてください。
- そのまま受け取る側は、項目名を打ち間違えても実行するまで気づけない
- 型のある関数で受け取ると、打ち間違えた行にその場で赤い線が出る
- 正しい項目名に直すと、どちらの受け取り方でも同じ商品名が読める
2 / 5
asで塞ぐのはごまかし
as を付ければ型検査は通りますが、中身を確かめてはくれません。
asで塞ぐ
const data =
(await res.json()) as Item[];
setItems(data);戻り値に型を書く
async function fetchItems():
Promise<Item[]> {
const res = await fetch(url);
const data: Item[] =
await res.json();
return data;
}3 / 5
呼び出しと型の対応
useEffect からは関数を呼ぶだけになり、外側は Item[] としか付き合いません。
型
| 書いたもの | 型 |
|---|---|
| fetchItems() | Promise<Item[]> |
| list | Item[] |
4 / 5
考えてみよう外しても進めます
API の返す形が変わったとき、直す場所はどこですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
取り直しを誰がやるか
絞り込みを手元でやるか、サーバーにやらせるかで通信の量が変わります。
手元で絞り込む
const shown = items.filter(
(i) => i.category === cat
);サーバーに絞らせる
const res = await fetch(
"/api/items?category=" + cat
);全部取ってから捨てるか、要る分だけ届くかの違いです。
1 / 5
React実践 - 依存で再取得
選び直すと何本飛ぶか
カテゴリを選び直して、飛んだリクエストが何本増えるか確かめてください。
- 選び直すたびに1本ずつ飛び、件数の行が増える
- 依存配列を空にすると1本だけになり、選び直しても動かない
- 並んでいる中身と選んだカテゴリが食い違うと朱色になる
2 / 5
取り直しの抜け
URL は書きかえたのに、依存配列を直し忘れる事故がよく起きます。
URL に条件を足し、依存配列は空のまま
選び直しても一覧が変わらず、原因を探すのに時間がかかる
依存配列だけ気にして URL の中身を見ない
画面と実際に飛んだリクエストが食い違う
effect の中で使った外の値は、全部依存配列に書きます。
3 / 5
カテゴリ別に取り直す
URL に条件を足し、依存配列にも入れると、選ぶたびに取り直します。
結果
| 選んだカテゴリ | 件数 |
|---|---|
| すべて | 5 件 |
| shoes | 2 件 |
| kitchen | 1 件 |
4 / 5
考えてみよう外しても進めます
カテゴリを選び直すたびに取り直したいとき、依存配列に書くものはどれですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
選び直すと何が起きるか
続けて選び直すと、通信は送った順に返るとは限りません。
shoesを選ぶ
1本目が飛ぶ。混んでいて1.2秒かかる
platesに変える
2本目が飛ぶ。0.3秒で返ってくる
2本目が先に返る
画面は plates になる
1本目が遅れて返る
画面が shoes に巻き戻る
選んだのは plates なのに、画面は shoes に戻ってしまいます。
1 / 5
React実践 - クリーンアップと競合
古い応答をたどる
実行を進めて、あとから返った古い応答が何をするか確かめてください。
- 先に飛んだほうが遅れて返り、あとから飛んだほうが先に返る
- 片付けの関数を返すと、遅れて返った古い応答は捨てられる
- 片付けを返さないと、古い応答が上書きして画面が巻き戻る
2 / 5
クリーンアップの勘違い
タイマーの後片付けと同じだと思っていると、書く場所を間違えます。
タイマーのときだけ片付けが要ると思う
取得でも古い応答を捨てる仕組みが要ることを見落とす
捨てる判定を待つ前に書く
応答を待つ前に判定しても意味が無く、素通りする
片付けの中で state を更新する
片付けは印を立てるだけで、状態は変えない
印を立てるのは片付け、捨てる判定は待ったあとです。
3 / 5
捨てる印を立てる
effect の中で印を作り、片付けの関数でその印を立てます。
片付けを返さない
useEffect(() => {
load();
// 印が無い
}, [category]);片付けを返す
useEffect(() => {
let ignore = false;
load();
return () => {
ignore = true;
};
}, [category]);違いは、片付けの関数を返しているかどうかだけです。
4 / 5
考えてみよう外しても進めます
続けて選び直したとき、古い応答が画面を上書きしないようにするにはどうしますか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
React実践 - POSTで送信
POSTの3つの意味
取得のときには要らなかった3つを、送るときは書き足します。
3つそろって、はじめてサーバーに出品データが届きます。
| 書くもの | 意味 |
|---|---|
| method | 何をしに来たか。書かないと取得になる |
| headers | 送る中身が何の形か。JSON だと伝える |
| body | 送る中身そのもの。文字にしてから渡す |
1 / 5
React実践 - POSTで送信
送る、返る、取り直す
最後まで進めてから、取り直しを書き忘れた場合と見くらべてください。
- 送る、返る、取り直すの3手が順に進む
- 取り直しを書き忘れると、作成に成功しても一覧は増えないまま
- 取り直すと、出品した1件が一覧に加わる
2 / 5
出品でつまずく所
送信を初めて書くときに、よく起きる3つです。
既定の送信を止め忘れる
ボタンを押すとページごと読み直されてしまう
価格を文字のまま送る
サーバー側で並べ替えが壊れる
送ったあと一覧を取り直さない
出品したのに一覧の件数が増えない
外から入った値を型のある形に直すのは、取得のときと同じ話です。
3 / 5
出品データを送る
既定の送信を止めてから、3つを書き足して送ります。
結果
| 入力した価格 | 送られる価格 |
|---|---|
| 文字の 6800 | 数の 6800 |
4 / 5
考えてみよう外しても進めます
出品フォームの送信を POST にするとき、かならず書くものはどれですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
旗を増やすと事故が増える
読み込み中と失敗と中身を別々の state に持つと、ありえない組み合わせまで書けてしまいます。
旗を3つ持つ
const [items, setItems] =
useState<Item[]>([]);
const [loading, setLoading] =
useState(true);
const [error, setError] =
useState("");1つの型にまとめる
type LoadState =
| { status: "loading" }
| { status: "success";
items: Item[] }
| { status: "error";
message: string };1 / 5
React実践 - 3状態を型で表す
型が防ぐ組み合わせ
旗の組み合わせを動かして、ありえない画面がいくつ作れるか確かめてください。
- 旗のままだと、読み込み中と失敗が同時に光る画面まで作れる
- 1つの型にまとめると、ありえない組み合わせは書けなくなる
- まとめたあとは、画面に出るランプがいつも1つだけになる
2 / 5
枝の外では読めない
状態ごとに分けても、枝の外でうっかり中身を読むと事故が起きます。
成功の枝の外で中身を読む
その時点の型に無いので、書いた時点で赤くなる
状態を確かめずに一覧を並べる
読み込み中や失敗のときに実行時エラーで画面が壊れる
成功の枝だけ足して失敗の枝を忘れる
失敗しても成功として扱われ、正しい表示にならない
型で守られるのは、かならず状態を見てから中身を読んだときだけです。
3 / 5
枝ごとに出し分ける
状態を見てから、枝の中だけで対応する表示に振り分けます。
state.status === "loading"状態を見てから判別state.message失敗の枝の中だけ読める画面
| 状態 | 出る表示 |
|---|---|
| loading | 読み込み中 |
| success | 一覧 |
| error | 読み込めませんでした |
4 / 5
考えてみよう外しても進めます
状態が読み込み中のとき、成功の枝にしかない中身を読もうとするとどうなりますか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
React実践 - ローディングUI
待つ間に何を見せるか
選び方は大きく3つあり、一覧の画面では骨組みが向いています。
板そのものは中身のない箱で、高さと背景色だけ付ければ板らしく見えます。
| 見せ方 | 伝わること |
|---|---|
| 何も出さない | 一瞬だけ真っ白になり、壊れているように見える |
| ぐるぐる回す | 待っていることは伝わるが、形は分からない |
| 骨組みを出す | これから出る形と同じ板を、先に並べておける |
1 / 5
React実践 - ローディングUI
跳ねるか跳ねないか
待たせ方と経過した時間を動かして、届いた瞬間にボタンが跳ねるか確かめてください。
- 出さないやぐるぐるだと、届いた瞬間に下のボタンが跳ねる
- 骨組みだと、届く前から3枚ぶんの場所が取ってある
- 時間を進めると、板がそのままカードに置き換わる
2 / 5
先に場所を取る
板を出す書き方は、中身が届く前と後で高さがほぼ同じになります。
何も出さない
{state.status === "loading" && null}板で場所を取る
{state.status === "loading" && (
<div className="skeleton-list">
<div className="skeleton" />
</div>
)}中身が届く前と後で高さがほぼ同じなので、画面が跳ねません。
3 / 5
外側のクラスを忘れると
板を出すだけでは、読み込みが終わっても残っていることに気づけません。
読み込み中の印を外し忘れる
取得が終わっても読み込み中の見た目が残る
クラス名を決め打ちで書く
読み込み中かどうかで見た目を切り替えられない
板の枚数を届く件数と関係なく増やす
実際より賑やかな一覧に見えてしまう
三項演算子で切り替えると、状態と見た目が1対1で結び付きます。
4 / 5
考えてみよう外しても進めます
商品が届いた瞬間に、下にあるボタンの位置が変わらないのはどれですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
500でも失敗にならない
サーバーが500を返しても、返事が来た時点で成功とみなされます。
そのまま受け取る
const res = await fetch("/api/items");
const data = await res.json();
// 中身がエラー説明でも素通りする自分で判定する
const res = await fetch("/api/items");
if (!res.ok) {
throw new Error("読み込みに失敗");
}res.ok は200番台のときだけ真です。偽なら自分で投げて catch へ落とします。
1 / 5
React実践 - エラーUI
再試行でどう変わるか
再試行に切り替えて、取り直す道がどこから開くか追ってください。
- 1回目は失敗が返り、自分で投げた先の catch を通る
- 再試行のあとは取り直しの道が開き、もう一度取りに行く
- 画面をエラー番号だけにすると、押す場所が消えて行き止まりになる
2 / 5
エラー画面のつまずき
再試行を作るときに、この3つでよく詰まります。
取り直す前に読み込み中へ戻さない
押してもエラーの画面のまま固まって見える
取り直しの印を依存配列に入れ忘れる
ボタンを押しても取り直しが走らない
エラー番号だけを出す
使う人が次に何をすればいいか分からない
理由と、使う人のせいではないことと、次にできることの3つを置きます。
3 / 5
再試行ボタンを作る
取り直しの印を依存配列に足すと、押すたびに値が変わってもう一度動きます。取り直す前に読み込み中へ戻すのを忘れないでください。
[category, reloadKey]依存配列に足すreloadKey + 1押すたびに値を変える結果
| 操作 | 画面 |
|---|---|
| 1回目の取得 | 読み込めませんでした と 再試行 |
| 再試行を押す | 5件のカードが並ぶ |
4 / 5
考えてみよう外しても進めます
再試行のボタンを押すと、useEffect がもう一度動くのはなぜですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
件数だけで判定しない
件数だけを見ると、取得中のあいだも0件に見えてしまいます。
件数だけで判定
{items.length === 0 && (
<div className="empty">...</div>
)}状態も見て判定
{state.status === "success" &&
state.items.length === 0 && (
<div className="empty">...</div>
)}取得中も0件も、件数だけを見ると同じ0に見えます。
1 / 5
React実践 - 空状態UI
取得中と0件を分ける
時間を動かして、返事が届く前に何が出ているか確かめてください。
- 状態を見ない判定は、届く前のあいだも空状態が出てしまう
- 状態も見て分けると、届くまでは読み込み中の表示になる
- 返事が届いてはじめて、本当に0件だったと分かる
2 / 5
空状態のつまずき
空状態を作るときに、この3つでよく詰まります。
件数だけで空状態を出す
取得中のあいだも一瞬空状態が出てしまう
空状態に文言だけ置く
使う人が次に進める場所がない
一覧側に件数の条件を足し忘れる
0件でも空の入れ物が残ったままになる
空状態を行き止まりにしないのが大事なところです。
3 / 5
出品への導線を作る
0件のときは、次に進めるボタンを1つ置きます。1件以上のときは一覧側の条件で切り替えます。
state.status === "success"取得中ではないか見るstate.items.length === 0件数を見る結果
| 選んだカテゴリ | 画面 |
|---|---|
| 本 0件 | まだ出品がありません と 出品する |
| すべて 5件 | 5件のカードが並ぶ |
4 / 5
考えてみよう外しても進めます
空状態を出す条件に、取得が成功したかどうかも含める理由は何ですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
見た目だけでは足りない
ボタンを押せなくするだけでは、Enter で送る道を止められません。
ボタンだけ止める
<button
disabled={pending}
>
出品する
</button>入口でも止める
if (pending) return;
setPending(true);ボタンの外の道は、処理の先頭でしか止められません。
1 / 5
React実践 - 送信中の制御
止め方を切り替える
送る道と止め方を切り替えて、送信が何回飛ぶか数えてください。
- ボタンを2回押す道なら、ボタンを止めるだけで1回に収まる
- Enter で2回送る道だと、ボタンを止めるだけでは2回とも飛ぶ
- 入口でも止めると、道を問わず1回で済む
2 / 5
二重送信のつまずき
送信中の制御を書くとき、ここでよくつまずきます。
戻す処理を try の中に書く
送信が失敗すると、ボタンが二度と押せなくなる
処理の先頭で止める行を忘れる
ボタン以外の道から送ると、また2件出品される
送信中にする行を書き忘れる
送っている間もボタンが押せたままになる
戻す処理は、かならず finally に置きます。
3 / 5
finallyで必ず戻す
成功しても失敗しても、finally で必ず送信中を解きます。送信の前後でボタンがどう変わるか確かめてください。
finally成功でも失敗でも必ず通る結果
| タイミング | ボタンの表示 |
|---|---|
| 送信を始めた直後 | 送信中、押せない |
| finally を通ったあと | 出品する、押せる |
4 / 5
考えてみよう外しても進めます
ボタンを押せなくするだけでは、二重送信を防げない場面はどれですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
