React Routerとアプリ設計の導入スライド

18 件(作成済み 11・導入不要 0・未作成 7・合計 55枚 / 11本)

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

React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計1レッスン

ルーティング導入

導入スライド 5

URLが変わらない代償

いまの fleama は、画面を切り替えても URL がずっと同じままです。

いまの状態起きること

画面を切り替えても URL が変わらない

気に入った商品を人に教えられない

戻るボタンを押す

アプリごと閉じてしまう

開き直す

必ず最初の画面に戻る

画面と URL が結び付いていないのが原因です。

1 / 5

React Routerとアプリ設計 - ルーティング導入

移動してカートを見る

移動の書き方を切り替えて、カートに入れた点数がどうなるか見比べてください。

  • a href にすると、サーバーへ行き、カートの点数が捨てられる
  • Link to のままだと、サーバーへ行かず、点数がそのまま残る
  • カートに入れた点数を動かすと、残る点数もその値に変わる
a タグと Link の違い

2 / 5

対応表を書く

一番外側を BrowserRouter で包み、Routes と Route で対応表を書きます。

<BrowserRouter>
<Routes>
<Route path="/"
path="/"URL
element={<Home />} />
element={<Home />}出す部品
</Routes>
</BrowserRouter>

3 / 5

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

React Router で押した移動は、サーバーへどう振る舞いますか。

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

4 / 5

URL の変化を見て、出す部品を差し替える

画面と URL を結び付けるしくみです。

5 / 5

React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計2レッスン

RoutesとRoute

導入スライド 5

対応表に行を足す

ページを増やすというのは、この対応表に行を足すことです。

<Routes>
<Route path="/"
element={<Home />} />
<Route
path="/items"
path="/items"新しい行
element={<ItemList />}
/>
</Routes>

1 / 5

React Routerとアプリ設計 - RoutesとRoute

URLとRouteの対応

開いた URL を切り替えて、対応表のどの行で止まるか追ってください。

  • どの行にも当たらない URL を選ぶと、画面に何も出なくなる
  • 当たる URL を選ぶと、その行だけが合うになり、他は素通りされる
  • ナビを Routes の中に書くを入れると、ナビが消える
URL がどの Route に当たるか

2 / 5

ナビをどこに置くか

同じナビでも、置く場所で共通か切り替わる部分かが決まります。

置いた場所結果

Routes の外に置く

全ページで共通のまま出続ける

Routes の中に置く

ページを移るたびに消えたり出たりする

取り違えると、ページを移るたびにナビが消えるアプリになります。

3 / 5

elementはJSXで渡す

element に渡すのは書かれた JSX です。関数のまま渡すと何も出ません。

以前の書き方

component={ItemList}

v7の書き方

element={<ItemList />}

ItemList とだけ書いて渡しても、何も出ません。

4 / 5

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

Routes は、中に並んだ Route のうちいくつを選んで出しますか。

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

5 / 5

React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計3レッスン

遷移を作る

導入スライド 5
React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計4レッスン

URLパラメータ

導入スライド 5

商品の数だけ書けない

出品されるたびに Route を1行足す、というわけにはいきません。

商品ごとに書く

<Route path="/items/1" ... /> <Route path="/items/2" ... /> <Route path="/items/3" ... />

1本のRoute

<Route path="/items/:id" element={<ItemDetail />} />

右の1行で、どの id が来ても同じ部品が受け取ります。

1 / 5

React Routerとアプリ設計 - URLパラメータ

idを動かして確かめる

URL の id を動かして、同じ Route から別の商品が出るのを見てください。

  • アドレスバーと useParams の値と一致した行が、一緒に変わる
  • 出品されていない id にすると、一致する商品が無くなる
  • Item の id を number で持つにすると、文字列と一致しなくなる
URL の中の id を読む

2 / 5

静かに一致しなくなる

型を number にしても動いてしまうので、気づきにくいまま壊れます。

書いたこと起きること

Item の id を number で持つ

文字列と一致せず、find が常に undefined になる

見つからないときの分岐を書かない

item.title を読んだところで止まる

Route の id と useParams の名前をずらす

受け取る値が undefined のまま残る

URL から来る値は必ず文字列です。

3 / 5

React Routerとアプリ設計 - URLパラメータ

見つかるかで分ける

見つかるかどうかで、画面に出す中身を分けてください。

find は見つからないと undefined を返します。

場面対応
ある商品名と価格を出す
無い見つかりませんでした、と出す
number型find が常に一致しない

4 / 5

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

/items/2 を開いたとき、useParams が返す id の型は何ですか。

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

5 / 5

React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計5レッスン

検索条件をURLに

導入スライド 5

URLかstateか

検索語を useState だけに持つと、URL は /items のままで打った言葉が乗りません。

stateだけに持つ

const [keyword, setKeyword] = useState(""); // URL は /items のまま

URLに置く

const [searchParams] = useSearchParams(); const keyword = searchParams.get("q") ?? "";

右は読み込み直しても、貼って送っても同じ絞り込みが再現できます。

1 / 5

React Routerとアプリ設計 - 検索条件をURLに

置き場所で相手が変わる

検索欄に打った言葉を選んでから、置き場所を state に変えて相手の画面を見てください。

  • URL に置くと、自分の画面と相手の画面が同じ件数にそろう
  • 絞り込みを state だけで持つに変えると、URL が動かず相手には伝わらない
  • 0件になる言葉を選ぶと、どちらの置き場所でも0件になる
絞り込みを URL に置く

2 / 5

getは無いとnull

searchParams.get は値が無いとき null を返すので、空文字にそろえて使います。

const [searchParams, setSearchParams] =
setSearchParamsURL を書き換える
useSearchParams();
const keyword =
searchParams.get("q") ?? "";
?? ""無いときは空文字にする
<input
value={keyword}
onChange={(e) =>
setSearchParams({ q: e.target.value })}
/>

3 / 5

React Routerとアプリ設計 - 検索条件をURLに

何をURLに置くか

人に送ったときに同じ画面が見えてほしいものだけを URL に置きます。

置くもの置かないもの
検索語入力途中のフォーム
並び順開いているかどうかのメニュー
ページ番号一時的な選択状態

4 / 5

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

検索した一覧を、そのまま人に送って同じ画面を見せたいとき、検索語をどこに置きますか。

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

5 / 5

React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計6レッスン

404ページ

導入スライド 5

Routesは対応表

Routes はいまの URL に一番よく合う Route を1つだけ選びます。

URLを開く

打ち間違えた URL や古いリンクが開かれる

対応表を見比べる

並んだ Route の中から一番よく合う行を探す

受ける行が無い

どの行にも当たらず、中身が空のまま残る

1 / 5

React Routerとアプリ設計 - 404ページ

どこまで線が届くか

開いた URL を切り替えて、線がどの行に届くか追ってください。

  • 打ち間違えた URL は、どの行にも当たらずアスタリスクの行が受ける
  • アスタリスクの行を消すと、受け皿が無くなり中身が空のまま残る
  • きちんと書いた URL は、それぞれの行にそのまま当たる
どこにも当たらなかった URL

2 / 5

アスタリスクで受ける

path にアスタリスクを書くと、他のどれにも当たらなかったとき用の行になります。

<Routes>
<Route path="/" element={<Home />} />
<Route path="/items"
element={<ItemList />} />
<Route path="*"
path="*"どれにも当たらないとき
element={<NotFound />} />
</Routes>

3 / 5

受け皿には出口を

404 のページで大事なのは、謝る文ではなく次にどこへ行けるかです。

出口が無い

return ( <h1>準備中</h1> );

Linkで出口を置く

return ( <> <h1>見つかりません</h1> <Link to="/">トップへ</Link> </> );

戻るボタンしか出口が無いと、そのまま離脱されます。

4 / 5

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

どの Route にも当たらなかった URL を受ける行の path はどれですか。

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

5 / 5

React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計7レッスン

つくる - ページ分割完了

導入スライド未作成
React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計8レッスン

第7章クイズ

導入スライド未作成
React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計9レッスン

見た目と機能の分離

導入スライド 5

React Routerとアプリ設計 - 見た目と機能の分離

2つの仕事を持つ部品

いまの ItemList は、通信の仕事と表示の仕事を1つの関数の中でやっています。

1つの関数が2つの理由で書き換わる状態になっています。

仕事中身
通信の仕事fetch と state の管理
表示の仕事JSX とクラス名で並べる

1 / 5

React Routerとアプリ設計 - 見た目と機能の分離

取る係と並べる係

取れた商品の数を動かして、同じ数が上から下へ渡っていくのを見てください。

  • 件数を動かすと、渡った数がそのまま画面まで届く
  • 表示担当に fetch を書くを入れると、表示担当の枠が朱色になる
  • そのとき表示担当の中に useState と fetch が並ぶ
取ってくる係と並べる係

2 / 5

分けると変わるコード

表示担当からは state と通信が消え、props だけを受け取る形になります。

1つの関数でやる

function ItemList() { const [items, setItems] = useState([]); useEffect(() => { fetch("/api/items"); }, []); return <div>{}</div>; }

表示担当を切り出す

export function ItemListView({ items, }: Props) { return <div className="list"> {items.map()} </div>; }

3 / 5

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

表示担当の ItemListView に書いてはいけないものはどれですか。

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

4 / 5

取る係と並べる係を分けると、同じ並べ方を別の一覧にも使い回せる

分けておくと、見た目だけ直したいときに得をします。

5 / 5

React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計10レッスン

合成で組み立てる

導入スライド 5

分岐が増える行き止まり

Layout に真偽値の props を足すたび、Layout が呼び出し元をぜんぶ知ることになります。

やりたいこと起きること

横に絞り込みを出したい

showSide と sideKind が増える

別の画面が増える

また真偽値と分岐が1本増える

枠が呼び出し元を知るほど、枠は使い回せなくなります。

1 / 5

React Routerとアプリ設計 - 合成で組み立てる

分岐か、穴を空けるか

Layout を使う画面の数を増やして、上と下の増え方を見比べてください。

  • 画面が増えるたび、上の分岐は1本ずつ伸びる
  • 下の穴は3つのままで増えない
  • 画面が増えすぎると上の枠が朱色になり、知りすぎたことが分かる
props で分岐するか、穴に差すか

2 / 5

穴の型を決める

真偽値の props を、ReactNode の穴に置き換えます。

真偽値で分岐する

type LayoutProps = { title: string; showSide: boolean; sideKind: string; };

穴を空けて受け取る

type LayoutProps = { header: ReactNode; side: ReactNode; children: ReactNode; };

穴が2つ以上あるときは、真ん中の主役を children にします。

3 / 5

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

Layout は、中に入る CategoryNav や ItemCard を知っている必要がありますか。

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

4 / 5

枠が中身を知るほど、枠は使い回せなくなる

真偽値の props が増えそうになったら、まず穴に置き換えられないか考えます。

5 / 5

React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計11レッスン

機能別フォルダ

導入スライド 5

まとめ方で変わる

同じ fleama のファイルを、種類別と機能別で置き直すとこう変わります。

種類でまとめる

components/ ItemList.tsx Cart.tsx hooks/ useCart.ts types/ cart.ts

機能でまとめる

features/ items/ ItemList.tsx cart/ Cart.tsx useCart.ts types.ts

1 / 5

React Routerとアプリ設計 - 機能別フォルダ

用事ごとに開く場所

直す用事を切り替えて、開くファイルがどこに散るか見てください。

  • 数量を足すにすると、種類別は3つのフォルダを行き来する
  • 機能ごと消すにすると、機能別はフォルダごと消せる
  • 並べ方を変えるでも、機能別は関係するファイルが近くにある
種類で置くか、機能で置くか

2 / 5

React Routerとアプリ設計 - 機能別フォルダ

置き場所の見分け方

その部品が fleama の商品を知っているかどうかで決めます。

知っていれば features、知らなければ components です。

部品置き場所
Layoutcomponents。商品を知らない
ItemListfeatures。商品を知っている
Cartfeatures。商品を知っている
ボタンの枠components。商品を知らない

3 / 5

importの道のり

移すと、呼ぶ側の道のりが変わります。型も features の下から読みます。

import { ItemList }
from "./features/items/ItemList";
./features/items/ItemList機能のフォルダを指す
import { Cart }
from "./features/cart/Cart";

4 / 5

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

features に入れないのは、どんな部品ですか。

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

5 / 5

React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計12レッスン

つくる - 設計リファクタ

導入スライド未作成
React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計13レッスン

第8章クイズ

導入スライド未作成
React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計14レッスン

購入フロー

導入スライド 5

書き換える項目を絞る

商品を丸ごと送り直すと、送り忘れた項目が消えます。

商品を丸ごと送る

await fetch(url, { method: "PUT", body: JSON.stringify(item), });

statusだけ送る

await fetch(url, { method: "PATCH", body: JSON.stringify({ status: "sold", }), });

送る項目を絞るほど、他の項目が消える事故が減ります。

1 / 5

React Routerとアプリ設計 - 購入フロー

送るときの3点セット

図解は POST の例ですが、method と headers と body の3点は PATCH でも同じです。1つずつ外してください。

  • method を外すと GET として送られてしまう
  • headers を外すと相手が形式を読み取れない
  • body にそのままオブジェクトを渡すと、読めない文字列が届く
POST のリクエストの3点セット

2 / 5

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

PATCH で status だけ送ると、商品名と価格はどうなりますか。

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

3 / 5

購入完了までの4手

購入するを押してから完了が出るまでを、順番に見ます。

購入するを押す

handleBuy が呼ばれる

PATCHを送る

status だけを sold にして送る

返事で差し替え

items の同じ id を新しい商品に置き換える

完了を表示

売り切れとして画面に出る

4 / 5

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

返ってきた商品をそのまま items に使うのはなぜですか。

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

5 / 5

React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計15レッスン

マイページ

導入スライド未作成
React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計16レッスン

仕上げ

導入スライド未作成
React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計17レッスン

自由拡張

導入スライド未作成
React Router・アプリ設計のコースサムネイル
React Routerとアプリ設計18レッスン

完成と次のステップ

導入スライド 5

React Routerとアプリ設計 - 完成と次のステップ

身についた6つの力

fleama を作りながら、できるようになったことを振り返ります。

身につけた力fleama でやったこと
props も state もイベントも型で守った
取得読み込み中とエラーと空を全部持たせた
フック取得もフォームも画面から切り離した
Contextテーマとユーザーをどこからでも読めるようにした
reducerカートの操作を型で網羅した
ルーティング5つの画面を URL で分けた

1 / 5

次に進む2つの道

何を優先したいかで、次に進む道が変わります。

Node.js入門

偽物のデータを本物のサーバーに置きかえる。残したい人はこちら

Next.js入門

画面をサーバー側で先に組み立てる。公開したい人はこちら

どちらから進んでも、fleama の画面はそのまま活かせます。

2 / 5

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

出品したデータを、画面を閉じても消えないようにしたいとき、次に進むのはどちらですか。

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

3 / 5

React Routerとアプリ設計 - 完成と次のステップ

1つだけ残った偽物

本物ではないところが、まだ1つ残っています。

画面を閉じると、出品したものは消えてしまいます。

// mock-api.json はブラウザの中だけの偽物

4 / 5

作りかけを本物にする作業は、初めて作る作業より達成感が大きい

62 レッスンかけて、自分の手で動くアプリに仕上げました。

5 / 5