React実践の導入スライド

23 件(作成済み 16・導入不要 0・未作成 7・合計 80枚 / 16本)

レッスンの導入の索引へ戻る

React実践のコースサムネイル
React実践1レッスン

完成形を触る

導入スライド未作成
React実践のコースサムネイル
React実践2レッスン

propsに型を付ける

導入スライド 5

型が無いと止まらない

型を書かないと、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 を文字で渡すと、型が違うとして止まる
props の型と渡す側

2 / 5

分割代入で受け取る

引数のところで、型を付けたまま分割代入して受け取ります。props. をくり返さずに item だけで扱えます。

type ItemCardProps = {
item: Item;
};
function ItemCard({ item }: ItemCardProps) {
{ item }分割代入で受け取る
: ItemCardProps型を付ける
return <p>{item.title}</p>;
}

3 / 5

商品の型を切り出す

商品の形は複数の場所で使うので、型を独立させておきます。

項目を個別に渡す

type ItemCardProps = { title: string; price: number; };

商品ごと渡す

type ItemCardProps = { item: Item; };

商品の項目が増えても、渡す側は書きかえずに済みます。

4 / 5

考えてみよう外しても進めます

商品の型を Item として独立させておく理由は何ですか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践3レッスン

useStateの型

導入スライド 5

初期値があるか、ないか

最初に何を入れるかで、TypeScript が型を決められるかが変わります。

初期値が空のまま

const [items, setItems] = useState([]); // items は never[] になる

山かっこで型を渡す

const [items, setItems] = useState<Item[]>([]); // items は Item[] になる

空配列からは中身の型が分からないので、自分で教えます。

1 / 5

React実践 - useStateの型

上下で入るか試す

取ってきた商品の件数を動かして、上と下のどちらに入るか見くらべてください。

  • 件数を増やすと、型を書いた上の段には入り、書かない下の段は弾かれる
  • 件数を0にすると下も通る。空のうちは差が出ない
  • 型を書いた側だけ、件数がいくつでも止まらない
useState に型を渡す

2 / 5

止まる場所を先に見る

もう1つ、まだ選ばれていない状態にも型が要ります。

書いたこと起きること

選択中の商品に型を書かずに中身を読む

何も選ばれていないときに実行時エラーで画面が壊れる

まだ無い状態を型で表さないまま進める

詳細画面を開くたびに同じ場所で落ちる

型に null を含めておくと、この事故をコード側で止められます。

3 / 5

2件の商品を型で持つ

items に型を付けて、2件の商品をそのまま初期値にします。

const [items, setItems] =
useState<Item[]>([
useState<Item[]>山かっこで型を渡す
{ id: "1", title: "スニーカー",
price: 4800 },
{ id: "2", title: "革靴",
price: 9800 },
]);

結果

idtitleprice
1スニーカー4800
2革靴9800

4 / 5

考えてみよう外しても進めます

選択中の商品の型に null を含めておくと、TypeScript は何をしてくれますか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践4レッスン

イベントの型

導入スライド 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 にすぐ渡せます。

function handleChange(
e: ChangeEvent<HTMLInputElement>
ChangeEvent<HTMLInputElement>入力欄のイベント型
) {
setKeyword(e.target.value);
}

結果

入力した文字画面の表示
スニーカースニーカー で検索中
革靴革靴 で検索中

4 / 5

考えてみよう外しても進めます

引数を受け取らずに呼ぶだけのボタンにも、イベントの型は必要ですか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践5レッスン

childrenの型

導入スライド 5

childrenにも型がいる

title だけ受け取っていた型に、はさんだ中身を受け取る children を足します。

titleだけの型

type CardProps = { title: string; };

childrenを足した型

type CardProps = { title: string; children: ReactNode; };

children という名前は決まっています。足すのは型のほうです。

1 / 5

React実践 - childrenの型

はさむものを変える

はさむものを変えて、上と下のどちらが受け取れるか確かめてください。

  • JSX をはさむと、上の ReactNode の段だけ通り、下の段は弾かれる
  • 文字をはさむと、上下どちらの段も受け取れる
  • オブジェクトをはさむと、上下とも弾かれる
children で受け取れるもの

2 / 5

型を書くときの事故

ReactNode の代わりに近い型を書くと、通りすぎたり狭すぎたりします。

書いたことどうなるか

children を any にする

画面に出せない値まで通り、間違いに気づけない

children を JSX.Element にする

文字や配列を渡すと型エラーになる

title だけ書いて children を足し忘れる

はさんで呼ぶと、渡す側が型エラーになる

ReactNode は広く通し、any は広すぎ、JSX.Element は狭すぎます。

3 / 5

Cardが描画される

children に型を足した Card に、価格の行をはさんで呼び出した結果です。

プレビュー

スニーカー

4800 円

function Card(
{ title, children }: CardProps
) {
return (
<div className="card">
<h2>{title}</h2>
{children}
</div>
);
}

4 / 5

考えてみよう外しても進めます

Card の型に children を足します。正しい書き方はどれですか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践6レッスン

つくる - ItemCard(TS)

導入スライド未作成
React実践のコースサムネイル
React実践7レッスン

第1章クイズ

導入スライド未作成
React実践のコースサムネイル
React実践8レッスン

モックAPIの世界

導入スライド 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

React実践のコースサムネイル
React実践9レッスン

fetchとasyncの復習

導入スライド 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 を探すと、途中で止まる
await が止めるのはどこか

2 / 5

2つのawaitを書く

返事を待ち、その中身を読み終わるまでもう一度待ちます。

async function loadItems() {
const res = await fetch("/api/items");
await fetch1回目の待ち
const data = await res.json();
await res.json()2回目の待ち
setLog(data.length + " 件");
}

結果

書き方画面に出るもの
取ってくる行だけ待つ長さが読めない
両方待つ5 件 / 先頭は スニーカー

3 / 5

書き忘れると

この2つが典型的な間違いです。

書いたこと起きること

読み取る行の await を忘れる

中身が入る前の状態のままで、件数が読めない

async を部品の関数まで付ける

部品全体が待つものになり、JSX を返せなくなる

エラーの多くは、このどちらかが原因です。

4 / 5

考えてみよう外しても進めます

React の部品そのものに async を付けられないのはなぜですか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践10レッスン

useEffectで初回取得

導入スライド 5

呼ぶ場所で結果が変わる

取得する処理を、どこに書くかで動き方がまったく変わります。

部品の中で直接呼ぶ

function App() { loadItems(); return <div>...</div>; }

useEffectの中で呼ぶ

function App() { useEffect(() => { loadItems(); }, []); return <div>...</div>; }

直接呼ぶと、取得で state が変わるたびにまた呼ばれ、止まらない輪になります。

1 / 5

React実践 - useEffectで初回取得

取得を1歩ずつ

1歩ずつ進めて、画面に何件並ぶか確かめてください。

  • 最後まで進めると、0件だったところにカードが並ぶ
  • 依存配列を外して最後まで進めると、左に輪ができて赤く光る
  • 配列があるときは初回だけ、外すと毎回動くとラベルが変わる
useEffect で初回に取ってくる

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 が空の配列のままです。

useEffect(() => {
async function load() {
const res = await fetch("/api/items");
const data = await res.json();
setItems(data);
}
load();
}, []);

経過

経過時間items
0ミリ秒空の配列
300ミリ秒5件のカード

4 / 5

考えてみよう外しても進めます

画面が出た直後、items が空の配列なのはなぜですか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践11レッスン

レスポンスに型を付ける

導入スライド 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[] としか付き合いません。

useEffect(() => {
async function load() {
const list = await fetchItems();
setItems(list);
}
load();
}, []);

書いたもの
fetchItems()Promise<Item[]>
listItem[]

4 / 5

考えてみよう外しても進めます

API の返す形が変わったとき、直す場所はどこですか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践12レッスン

依存で再取得

導入スライド 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 に条件を足し、依存配列にも入れると、選ぶたびに取り直します。

useEffect(() => {
async function load() {
const res = await fetch(
"/api/items?category=" + category
);
const data: Item[] = await res.json();
setItems(data);
}
load();
}, [category]);

結果

選んだカテゴリ件数
すべて5 件
shoes2 件
kitchen1 件

4 / 5

考えてみよう外しても進めます

カテゴリを選び直すたびに取り直したいとき、依存配列に書くものはどれですか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践13レッスン

クリーンアップと競合

導入スライド 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実践のコースサムネイル
React実践14レッスン

POSTで送信

導入スライド 5

React実践 - POSTで送信

POSTの3つの意味

取得のときには要らなかった3つを、送るときは書き足します。

3つそろって、はじめてサーバーに出品データが届きます。

書くもの意味
method何をしに来たか。書かないと取得になる
headers送る中身が何の形か。JSON だと伝える
body送る中身そのもの。文字にしてから渡す

1 / 5

React実践 - POSTで送信

送る、返る、取り直す

最後まで進めてから、取り直しを書き忘れた場合と見くらべてください。

  • 送る、返る、取り直すの3手が順に進む
  • 取り直しを書き忘れると、作成に成功しても一覧は増えないまま
  • 取り直すと、出品した1件が一覧に加わる
POSTで送信

2 / 5

出品でつまずく所

送信を初めて書くときに、よく起きる3つです。

書いたこと起きること

既定の送信を止め忘れる

ボタンを押すとページごと読み直されてしまう

価格を文字のまま送る

サーバー側で並べ替えが壊れる

送ったあと一覧を取り直さない

出品したのに一覧の件数が増えない

外から入った値を型のある形に直すのは、取得のときと同じ話です。

3 / 5

出品データを送る

既定の送信を止めてから、3つを書き足して送ります。

e.preventDefault();
const res = await fetch("/api/items", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title,
price: Number(price),
}),
});

結果

入力した価格送られる価格
文字の 6800数の 6800

4 / 5

考えてみよう外しても進めます

出品フォームの送信を POST にするとき、かならず書くものはどれですか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践15レッスン

つくる - 一覧のAPI駆動化

導入スライド未作成
React実践のコースサムネイル
React実践16レッスン

第2章クイズ

導入スライド未作成
React実践のコースサムネイル
React実践17レッスン

3状態を型で表す

導入スライド 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つだけになる
3状態を型で表す

2 / 5

枝の外では読めない

状態ごとに分けても、枝の外でうっかり中身を読むと事故が起きます。

書いたこと起きること

成功の枝の外で中身を読む

その時点の型に無いので、書いた時点で赤くなる

状態を確かめずに一覧を並べる

読み込み中や失敗のときに実行時エラーで画面が壊れる

成功の枝だけ足して失敗の枝を忘れる

失敗しても成功として扱われ、正しい表示にならない

型で守られるのは、かならず状態を見てから中身を読んだときだけです。

3 / 5

枝ごとに出し分ける

状態を見てから、枝の中だけで対応する表示に振り分けます。

{state.status === "loading" &&
state.status === "loading"状態を見てから判別
<p>読み込み中</p>}
{state.status === "error" && (
<p>{state.message}</p>
state.message失敗の枝の中だけ読める
)}
{state.status === "success" &&
<div>...</div>}

画面

状態出る表示
loading読み込み中
success一覧
error読み込めませんでした

4 / 5

考えてみよう外しても進めます

状態が読み込み中のとき、成功の枝にしかない中身を読もうとするとどうなりますか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践18レッスン

ローディングUI

導入スライド 5

React実践 - ローディングUI

待つ間に何を見せるか

選び方は大きく3つあり、一覧の画面では骨組みが向いています。

板そのものは中身のない箱で、高さと背景色だけ付ければ板らしく見えます。

見せ方伝わること
何も出さない一瞬だけ真っ白になり、壊れているように見える
ぐるぐる回す待っていることは伝わるが、形は分からない
骨組みを出すこれから出る形と同じ板を、先に並べておける

1 / 5

React実践 - ローディングUI

跳ねるか跳ねないか

待たせ方と経過した時間を動かして、届いた瞬間にボタンが跳ねるか確かめてください。

  • 出さないやぐるぐるだと、届いた瞬間に下のボタンが跳ねる
  • 骨組みだと、届く前から3枚ぶんの場所が取ってある
  • 時間を進めると、板がそのままカードに置き換わる
ローディングUI

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

React実践のコースサムネイル
React実践19レッスン

エラーUI

導入スライド 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

再試行ボタンを作る

取り直しの印を依存配列に足すと、押すたびに値が変わってもう一度動きます。取り直す前に読み込み中へ戻すのを忘れないでください。

const [reloadKey, setReloadKey] =
useState(0);
useEffect(() => {
// 取得の処理
}, [category, reloadKey]);
[category, reloadKey]依存配列に足す
<button
onClick={() =>
setReloadKey(reloadKey + 1)}>
reloadKey + 1押すたびに値を変える
再試行
</button>

結果

操作画面
1回目の取得読み込めませんでした と 再試行
再試行を押す5件のカードが並ぶ

4 / 5

考えてみよう外しても進めます

再試行のボタンを押すと、useEffect がもう一度動くのはなぜですか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践20レッスン

空状態UI

導入スライド 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件だったと分かる
読み込み中と 0 件

2 / 5

空状態のつまずき

空状態を作るときに、この3つでよく詰まります。

書いたこと起きること

件数だけで空状態を出す

取得中のあいだも一瞬空状態が出てしまう

空状態に文言だけ置く

使う人が次に進める場所がない

一覧側に件数の条件を足し忘れる

0件でも空の入れ物が残ったままになる

空状態を行き止まりにしないのが大事なところです。

3 / 5

出品への導線を作る

0件のときは、次に進めるボタンを1つ置きます。1件以上のときは一覧側の条件で切り替えます。

{state.status === "success" &&
state.status === "success"取得中ではないか見る
state.items.length === 0 && (
state.items.length === 0件数を見る
<div className="empty">
<p>まだ出品がありません</p>
<button>出品する</button>
</div>
)}

結果

選んだカテゴリ画面
本 0件まだ出品がありません と 出品する
すべて 5件5件のカードが並ぶ

4 / 5

考えてみよう外しても進めます

空状態を出す条件に、取得が成功したかどうかも含める理由は何ですか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践21レッスン

送信中の制御

導入スライド 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 で必ず送信中を解きます。送信の前後でボタンがどう変わるか確かめてください。

try {
await fetch("/api/items", {
method: "POST",
body: JSON.stringify(sent),
});
} finally {
finally成功でも失敗でも必ず通る
setPending(false);
}

結果

タイミングボタンの表示
送信を始めた直後送信中、押せない
finally を通ったあと出品する、押せる

4 / 5

考えてみよう外しても進めます

ボタンを押せなくするだけでは、二重送信を防げない場面はどれですか。

選ぶと、この枚の中で答えと理由を確かめられます。

5 / 5

React実践のコースサムネイル
React実践22レッスン

つくる - 3状態UI完備

導入スライド未作成
React実践のコースサムネイル
React実践23レッスン

第3章クイズ

導入スライド未作成