Slide 1

Slide 1 text

Node学園 42時限目 ー Next.js AppRouterについて ServerAction で Progressive Enhancement は どこまで頑張れるか?

Slide 2

Slide 2 text

自己紹介 ■ Takepepe(吉井 健文) ■ フロントエンドエンジニア ■ 社内横断開発組織に所属 ■ フロントエンド開発の横断サポート

Slide 3

Slide 3 text

実践Next.js – App Router で進化する Web アプリ開発 ■ 2024.3/16 技術評論社より刊行 ■ Next.js App Router を題材にした書籍 ■ 一通りの機能を備えたサンプル App を対象に解説 ■ 公式ドキュメントの分かりづらい箇所を重点的に

Slide 4

Slide 4 text

■ 【1】Progressive Enhancement に関する書籍内容の紹介 ■ 【2】Progressive Enhancement 対応はどこまでやるべきか? ■ 【3】Server Action に関する近況アップデート Agenda

Slide 5

Slide 5 text

【1】Progressive Enhancement に関する    書籍内容の紹介

Slide 6

Slide 6 text

■ Progressive Enhancement とは? Progressive Enhancement と React 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 7

Slide 7 text

■ Progressive Enhancement とは? ・ MDN引用   https://developer.mozilla.org/ja/docs/Glossary/Progressive_Enhancement Progressive Enhancement と React 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 8

Slide 8 text

■ Progressive Enhancement とは? ・ MDN引用   https://developer.mozilla.org/ja/docs/Glossary/Progressive_Enhancement   > 可能な限り多くのユーザーに不可欠なコンテンツと   機能のベースラインを提供することを中心とした設計哲学 Progressive Enhancement と React 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 9

Slide 9 text

React や Next.js ドキュメントでも使用されているワード ■ Progressive Enhancement とは? ・ MDN引用   https://developer.mozilla.org/ja/docs/Glossary/Progressive_Enhancement   > 可能な限り多くのユーザーに不可欠なコンテンツと   機能のベースラインを提供することを中心とした設計哲学 Progressive Enhancement と React 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 10

Slide 10 text

■ Server Component/Server Action で身近になった設計指針 Progressive Enhancement と React 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 11

Slide 11 text

■ Server Component/Server Action で身近になった設計指針 ・ useFormState と Server Action により、JS オフでも POST が可能に Progressive Enhancement と React 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 12

Slide 12 text

■ Server Component/Server Action で身近になった設計指針 ・ useFormState と Server Action により、JS オフでも POST が可能に ・ ハイドレーション前でも、Form の送信が可能 Progressive Enhancement と React 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 13

Slide 13 text

API Client & API Routes による従来アプローチでは不可能だった実装 ■ Server Component/Server Action で身近になった設計指針 ・ useFormState と Server Action により、JS オフでも POST が可能に ・ ハイドレーション前でも、Form の送信が可能 Progressive Enhancement と React 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 14

Slide 14 text

Form 機能のベースラインとして、 JS オフでも最低限 POST ができるように ■ Server Component/Server Action で身近になった設計指針 ・ useFormState と Server Action により、JS オフでも POST が可能に ・ ハイドレーション前でも、Form の送信が可能 Progressive Enhancement と React 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 15

Slide 15 text

■ Form 機能のベースラインとして留意すること JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 16

Slide 16 text

■ Form 機能のベースラインとして留意すること ・ useState で入力値を管理しない JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 17

Slide 17 text

■ Form 機能のベースラインとして留意すること ・ useState で入力値を管理しない ・ Form は非制御コンポーネントを使用して構成 JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 18

Slide 18 text

■ Form 機能のベースラインとして留意すること ・ useState で入力値を管理しない ・ Form は非制御コンポーネントを使用して構成 ・  を活用 JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 19

Slide 19 text

JS オフでは useState が機能しないため ■ Form 機能のベースラインとして留意すること ・ useState で入力値を管理しない ・ Form は非制御コンポーネントを使用して構成 ・  を活用 JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 20

Slide 20 text

■ useFormState フックを使用する JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 21

Slide 21 text

■ useFormState フックを使用する JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介 const [formState, formDispatch] = useFormState(updateAction, initialFormState);

Slide 22

Slide 22 text

const [formState, formDispatch] = useFormState(updateAction, initialFormState); ■ useFormState フックを使用する ・ Client Component で使用するフック JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 23

Slide 23 text

const [formState, formDispatch] = useFormState(updateAction, initialFormState); ■ useFormState フックを使用する ・ Client Component で使用するフック ・ 第 1 引数には Server Action を渡す(updateAction) JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 24

Slide 24 text

const [formState, formDispatch] = useFormState(updateAction, initialFormState); ■ useFormState フックを使用する ・ Client Component で使用するフック ・ 第 1 引数には Server Action を渡す(updateAction) ・ 第 2 引数には「状態(initialFormState)」を渡す JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 25

Slide 25 text

const [formState, formDispatch] = useFormState(updateAction, initialFormState); ■ useFormState フックを使用する ・ Client Component で使用するフック ・ 第 1 引数には Server Action を渡す(updateAction) ・ 第 2 引数には「状態(initialFormState)」を渡す ・ Submit を跨いで更新される formState を使う JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 26

Slide 26 text

const [formState, formDispatch] = useFormState(updateAction, initialFormState); ■ useFormState フックを使用する ・ Client Component で使用するフック ・ 第 1 引数には Server Action を渡す(updateAction) ・ 第 2 引数には「状態(initialFormState)」を渡す ・ Submit を跨いで更新される formState を使う ・  の action 属性には formDispatch を使う JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 27

Slide 27 text

const [formState, formDispatch] = useFormState(updateAction, initialFormState); ■ useFormState フックを使用する ・ Client Component で使用するフック ・ 第 1 引数には Server Action を渡す(updateAction) ・ 第 2 引数には「状態(initialFormState)」を渡す ・ Submit を跨いで更新される formState を使う ・  の action 属性には formDispatch を使う JS オフでも機能する Form 実装 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 28

Slide 28 text

export async function updateAction( prevState: FormState, formData: FormData ): Promise {} useFormState に渡す ServerAction 【1】Progressive Enhancement に関する書籍内容の紹介 useFormState に渡す Server Action は、実装制約を満たす必要がある

Slide 29

Slide 29 text

export async function updateAction( prevState: FormState, formData: FormData ): Promise {} useFormState に渡す ServerAction 【1】Progressive Enhancement に関する書籍内容の紹介 第一引数に FormState をとり、FormState を返す非同期関数とすること

Slide 30

Slide 30 text

export type FormState = { title: string; description: string; updatedAt: string; error: Error | null; }; type Error = { message: string; status: number; fieldErrors?: Record; }; useFormState に渡す State(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 Error が発生したか否かを判定する状態をもつ

Slide 31

Slide 31 text

export type FormState = { title: string; description: string; updatedAt: string; error: Error | null; }; type Error = { message: string; status: number; fieldErrors?: Record; }; useFormState に渡す State(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 Error が発生したか否かを判定する状態をもつ

Slide 32

Slide 32 text

ServerAction 内で発生したエラー表現(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 Server Action ではエラーをどう扱うか? export async function updateAction(prevState: FormState, formData: FormData): Promise {

Slide 33

Slide 33 text

ServerAction 内で発生したエラー表現(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 戻り値の FormState で判別する export async function updateAction(prevState: FormState, formData: FormData): Promise {

Slide 34

Slide 34 text

export async function updateAction(prevState: FormState, formData: FormData): Promise { try { // ★: バリデーションエラーが発生した場合 catch 句へ const payload = validateFormData(formData); // ...省略 } catch (err) { // ★: Zod のバリデーションエラーをマッピング if (err instanceof ZodError) { return handleError(prevState, { ...errors[400], fieldErrors: transformFiledErrors(err), }); } return handleError(prevState, errors[500]); } } ServerAction 内で発生したエラー表現(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 例えば、バリデーションエラーが発生した場合

Slide 35

Slide 35 text

export async function updateAction(prevState: FormState, formData: FormData): Promise { try { // ★: バリデーションエラーが発生した場合 catch 句へ const payload = validateFormData(formData); // ...省略 } catch (err) { // ★: Zod のバリデーションエラーをマッピング if (err instanceof ZodError) { return handleError(prevState, { ...errors[400], fieldErrors: transformFiledErrors(err), }); } return handleError(prevState, errors[500]); } } ServerAction 内で発生したエラー表現(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 例えば、バリデーションエラーが発生した場合

Slide 36

Slide 36 text

export async function updateAction(prevState: FormState, formData: FormData): Promise { try { // ★: バリデーションエラーが発生した場合 catch 句へ const payload = validateFormData(formData); // ...省略 } catch (err) { // ★: Zod のバリデーションエラーをマッピング if (err instanceof ZodError) { return handleError(prevState, { ...errors[400], fieldErrors: transformFiledErrors(err), }); } return handleError(prevState, errors[500]); } } ServerAction 内で発生したエラー表現(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 バリデーションエラーが throw される

Slide 37

Slide 37 text

export async function updateAction(prevState: FormState, formData: FormData): Promise { try { // ★: バリデーションエラーが発生した場合 catch 句へ const payload = validateFormData(formData); // ...省略 } catch (err) { // ★: Zod のバリデーションエラーをマッピング if (err instanceof ZodError) { return handleError(prevState, { ...errors[400], fieldErrors: transformFiledErrors(err), }); } return handleError(prevState, errors[500]); } } ServerAction 内で発生したエラー表現(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 handleError 関数でエラー発生状態の FormState を返す

Slide 38

Slide 38 text

export async function updateAction(prevState: FormState, formData: FormData): Promise { try { // ★: バリデーションエラーが発生した場合 catch 句へ const payload = validateFormData(formData); // ...省略 } catch (err) { // ★: Zod のバリデーションエラーをマッピング if (err instanceof ZodError) { return handleError(prevState, { ...errors[400], fieldErrors: transformFiledErrors(err), }); } return handleError(prevState, errors[500]); } } ServerAction 内で発生したエラー表現(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 FormState に Error が含まれていたら「エラー文言」を表示する

Slide 39

Slide 39 text

onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 JS オフ環境では action が即座に実行される

Slide 40

Slide 40 text

onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 JS オン環境では action の前に onSubmit が実行される

Slide 41

Slide 41 text

function handleSubmit(event: FormEvent) { try { const formData = new FormData(event.currentTarget); // バリデーションエラーが発生した場合 catch 句へ validateFormData(formData); // ...省略(何もしない) } catch (err) { //★: Form のサブミット(action 実行)を中止 event.preventDefault(); // ...省略 } } onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 JS オン環境では action の前に onSubmit が実行される

Slide 42

Slide 42 text

function handleSubmit(event: FormEvent) { try { const formData = new FormData(event.currentTarget); // バリデーションエラーが発生した場合 catch 句へ validateFormData(formData); // ...省略(何もしない) } catch (err) { //★: Form のサブミット(action 実行)を中止 event.preventDefault(); // ...省略 } } onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 JS オン環境では action の前にバリデーションを実行する

Slide 43

Slide 43 text

function handleSubmit(event: FormEvent) { try { const formData = new FormData(event.currentTarget); // バリデーションエラーが発生した場合 catch 句へ validateFormData(formData); // ...省略(何もしない) } catch (err) { //★: Form のサブミット(action 実行)を中止 event.preventDefault(); // ...省略 } } onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 JS オン環境では、不正な入力値の場合「 Submit を中止する」

Slide 44

Slide 44 text

function handleSubmit(event: FormEvent) { try { const formData = new FormData(event.currentTarget); // バリデーションエラーが発生した場合 catch 句へ validateFormData(formData); // ...省略(何もしない) } catch (err) { //★: Form のサブミット(action 実行)を中止 event.preventDefault(); // ...省略 } } onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 JS オン環境では、不正な入力値の場合「 Submit を中止する」

Slide 45

Slide 45 text

function handleSubmit(event: FormEvent) { try { const formData = new FormData(event.currentTarget); // バリデーションエラーが発生した場合 catch 句へ validateFormData(formData); // ...省略(何もしない) } catch (err) { //★: Form のサブミット(action 実行)を中止 event.preventDefault(); // ...省略 } } onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介 正常入力の場合、Submit は中止しない -> action が実行される

Slide 46

Slide 46 text

■ 事前バリデーションは「 より良い体験の一部」という方針 onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 47

Slide 47 text

■ 事前バリデーションは「 より良い体験の一部」という方針 ・ JS オフ時でも、Form の送信はできる onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 48

Slide 48 text

■ 事前バリデーションは「 より良い体験の一部」という方針 ・ JS オフ時でも、Form の送信はできる ・ JS オフ時でも、Server Action 内でバリデーションはする onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 49

Slide 49 text

■ 事前バリデーションは「 より良い体験の一部」という方針 ・ JS オフ時でも、Form の送信はできる ・ JS オフ時でも、Server Action 内でバリデーションはする ・ JS オン時には、追加で事前バリデーションをする onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 50

Slide 50 text

「無駄に Server Action が送られないなら、より嬉しいよね」という方針 ■ 事前バリデーションは「 より良い体験の一部」という方針 ・ JS オフ時でも、Form の送信はできる ・ JS オフ時でも、Server Action 内でバリデーションはする ・ JS オン時には、追加で事前バリデーションをする onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 51

Slide 51 text

詳細は「実践 Next.js」をご覧ください ■ 事前バリデーションは「 より良い体験の一部」という方針 ・ JS オフ時でも、Form の送信はできる ・ JS オフ時でも、Server Action 内でバリデーションはする ・ JS オン時には、追加で事前バリデーションをする onSubmit による事前バリデーション(書籍例) 【1】Progressive Enhancement に関する書籍内容の紹介

Slide 52

Slide 52 text

【2】Progressive Enhancement 対応は    どこまでやるべきか?

Slide 53

Slide 53 text

■ useFormState で確保した State を活用すると、それなりに減らせる JSオン/オフで、どこまで差分を減らせるか? 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 54

Slide 54 text

■ useFormState で確保した State を活用すると、それなりに減らせる ・ Form 送信をして、バリデーションエラーを表示する JSオン/オフで、どこまで差分を減らせるか? 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 55

Slide 55 text

■ useFormState で確保した State を活用すると、それなりに減らせる ・ Form 送信をして、バリデーションエラーを表示する ・ Form 送信をして、エラーモーダルを表示する JSオン/オフで、どこまで差分を減らせるか? 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 56

Slide 56 text

■ useFormState で確保した State を活用すると、それなりに減らせる ・ Form 送信をして、バリデーションエラーを表示する ・ Form 送信をして、エラーモーダルを表示する ・ https://github.com/takefumi-yoshii/useformstate-example JSオン/オフで、どこまで差分を減らせるか? 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 57

Slide 57 text

■ 実装アプローチが根本的に異なる 「対応をどこまでやるべきか?」という線引きが必要 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 58

Slide 58 text

■ 実装アプローチが根本的に異なる ・ 「JS オフでも動くForm」を考えることは、これまでなかった 「対応をどこまでやるべきか?」という線引きが必要 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 59

Slide 59 text

■ 実装アプローチが根本的に異なる ・ 「JS オフでも動くForm」を考えることは、これまでなかった ・ ブラウザに保持される State 無しでロジックが組めるか? 「対応をどこまでやるべきか?」という線引きが必要 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 60

Slide 60 text

■ 実装アプローチが根本的に異なる ・ 「JS オフでも動くForm」を考えることは、これまでなかった ・ ブラウザに保持される State 無しでロジックが組めるか? ・ JS オン/オフ、どちらも考慮された実装を維持できるか? 「対応をどこまでやるべきか?」という線引きが必要 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 61

Slide 61 text

従来の知識で通用しない場面が出てくる可能性もあり ■ 実装アプローチが根本的に異なる ・ 「JS オフでも動くForm」を考えることは、これまでなかった ・ ブラウザに保持される State 無しでロジックが組めるか? ・ JS オン/オフ、どちらも考慮された実装を維持できるか? 「対応をどこまでやるべきか?」という線引きが必要 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 62

Slide 62 text

■ 要件定義が細かく決められている現場の場合、合意形成が必要 「対応をどこまでやるべきか?」という線引きが必要 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 63

Slide 63 text

■ 要件定義が細かく決められている現場の場合、合意形成が必要 ・ 要件定義では、どのように明文化するのか? 「対応をどこまでやるべきか?」という線引きが必要 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 64

Slide 64 text

■ 要件定義が細かく決められている現場の場合、合意形成が必要 ・ 要件定義では、どのように明文化するのか? ・ 手動・自動テストにおいて、どのように検証するのか? 「対応をどこまでやるべきか?」という線引きが必要 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 65

Slide 65 text

ステークホルダー間で合意不要、開発者意思で実装できるなら問題なし ■ 要件定義が細かく決められている現場の場合、合意形成が必要 ・ 要件定義では、どのように明文化するのか? ・ 手動・自動テストにおいて、どのように検証するのか? 「対応をどこまでやるべきか?」という線引きが必要 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 66

Slide 66 text

■ JS オフ環境でも使用できる(動機づけとして弱い) Progressive Enhancement を維持する目的は? 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 67

Slide 67 text

■ JS オフ環境でも使用できる(動機づけとして弱い) ■ ハイドレーションに関係なく即座に Form 送信ができる Progressive Enhancement を維持する目的は? 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 68

Slide 68 text

■ JS オフ環境でも使用できる(動機づけとして弱い) ■ ハイドレーションに関係なく即座に Form 送信ができる ・ ロースペックデバイスに効果あり? Progressive Enhancement を維持する目的は? 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 69

Slide 69 text

■ JS オフ環境でも使用できる(動機づけとして弱い) ■ ハイドレーションに関係なく即座に Form 送信ができる ・ ロースペックデバイスに効果あり? ・ 重厚なページで効果あり? Progressive Enhancement を維持する目的は? 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 70

Slide 70 text

■ JS オフ環境でも使用できる(動機づけとして弱い) ■ ハイドレーションに関係なく即座に Form 送信ができる ・ ロースペックデバイスに効果あり? ・ 重厚なページで効果あり? ・ INP(Core Web Vitals)に効果あり? Progressive Enhancement を維持する目的は? 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 71

Slide 71 text

Pros / Cons を検討のうえ判断が必要 ■ JS オフ環境でも使用できる(動機づけとして弱い) ■ ハイドレーションに関係なく即座に Form 送信ができる ・ ロースペックデバイスに効果あり? ・ 重厚なページで効果あり? ・ INP(Core Web Vitals)に効果あり? Progressive Enhancement を維持する目的は? 【2】Progressive Enhancement 対応はどこまでやるべきか?

Slide 72

Slide 72 text

【3】Server Action に関する近況アップデート

Slide 73

Slide 73 text

■ 【A】useActionState が生える 書籍刊行から1ヶ月。この間に起きたアップデート 【3】Server Action に関する近況アップデート

Slide 74

Slide 74 text

■ 【A】useActionState が生える ■ 【B】Parallel Routes のバグが解消 書籍刊行から1ヶ月。この間に起きたアップデート 【3】Server Action に関する近況アップデート

Slide 75

Slide 75 text

いずれも、書籍サンプルに小さな影響あり ■ 【A】useActionState が生える ■ 【B】Parallel Routes のバグが解消 書籍刊行から1ヶ月。この間に起きたアップデート 【3】Server Action に関する近況アップデート

Slide 76

Slide 76 text

■ useActionState とは? 【A】useActionState が生える 【3】Server Action に関する近況アップデート https://github.com/facebook/react/pull/28491

Slide 77

Slide 77 text

■ useActionState とは? ・ Renames useFormState to useActionState 【A】useActionState が生える 【3】Server Action に関する近況アップデート https://github.com/facebook/react/pull/28491

Slide 78

Slide 78 text

■ useActionState とは? ・ Renames useFormState to useActionState ・ Adds a pending state to the returned tuple 【A】useActionState が生える 【3】Server Action に関する近況アップデート https://github.com/facebook/react/pull/28491

Slide 79

Slide 79 text

■ useActionState とは? ・ Renames useFormState to useActionState ・ Adds a pending state to the returned tuple ・ Moves the hook to the 'react' package 【A】useActionState が生える 【3】Server Action に関する近況アップデート https://github.com/facebook/react/pull/28491

Slide 80

Slide 80 text

■ useFormState と useActionState の違い const [formState, formDispatch] = useFormState(updateAction, initialFormState); const [isPending] = useFormStatus(); 【A】useActionState が生える 【3】Server Action に関する近況アップデート isPending の参照のために useFormStatus を併用する必要がある

Slide 81

Slide 81 text

■ useFormState と useActionState の違い const [formState, formDispatch, isPending] = useActionState(updateAction, initialFormState); 【A】useActionState が生える 【3】Server Action に関する近況アップデート useActionStatus では戻り値に isPending が含まれる

Slide 82

Slide 82 text

■ useFormState -> useActionState なぜ? 【A】useActionState が生える 【3】Server Action に関する近況アップデート https://github.com/facebook/react/pull/28491

Slide 83

Slide 83 text

■ useFormState -> useActionState なぜ? ・ 実態として、Form ではなくAction の状態を参照している 【A】useActionState が生える 【3】Server Action に関する近況アップデート https://github.com/facebook/react/pull/28491

Slide 84

Slide 84 text

■ useFormState -> useActionState なぜ? ・ 実態として、Form ではなくAction の状態を参照している ・ ReactDOM への依存はない 【A】useActionState が生える 【3】Server Action に関する近況アップデート https://github.com/facebook/react/pull/28491

Slide 85

Slide 85 text

■ useFormState -> useActionState なぜ? ・ 実態として、Form ではなくAction の状態を参照している ・ ReactDOM への依存はない ・ "isPending" を Action と関連づけることで混乱を避ける 【A】useActionState が生える 【3】Server Action に関する近況アップデート https://github.com/facebook/react/pull/28491

Slide 86

Slide 86 text

■ 書籍では useFormState のサンプルを多数掲載していますが、、、、 【A】useActionState が生える 【3】Server Action に関する近況アップデート

Slide 87

Slide 87 text

■ 書籍では useFormState のサンプルを多数掲載していますが、、、、 ・ useFormState が非推奨 というわけではない 【A】useActionState が生える 【3】Server Action に関する近況アップデート

Slide 88

Slide 88 text

■ 書籍では useFormState のサンプルを多数掲載していますが、、、、 ・ useFormState が非推奨 というわけではない ・ ただし useActionState を優先するように促される見込み 【A】useActionState が生える 【3】Server Action に関する近況アップデート

Slide 89

Slide 89 text

■ 書籍では useFormState のサンプルを多数掲載していますが、、、、 ・ useFormState が非推奨 というわけではない ・ ただし useActionState を優先するように促される見込み ・ 実装詳細に関しては、サンプルに大きくは影響なし 【A】useActionState が生える 【3】Server Action に関する近況アップデート

Slide 90

Slide 90 text

今後は useActionState を使用した方が望ましい ■ 書籍では useFormState のサンプルを多数掲載していますが、、、、 ・ useFormState が非推奨 というわけではない ・ ただし useActionState を優先するように促される見込み ・ 実装詳細に関しては、サンプルに大きくは影響なし 【A】useActionState が生える 【3】Server Action に関する近況アップデート

Slide 91

Slide 91 text

■ Parallel Routes モーダル内の Server Action バグ 【B】Parallel Routes のバグが解消 【3】Server Action に関する近況アップデート

Slide 92

Slide 92 text

■ Parallel Routes モーダル内の Server Action バグ ・ 実は、開いたモーダル内で「いいね」を押下するとクラッシュする 【B】Parallel Routes のバグが解消 【3】Server Action に関する近況アップデート

Slide 93

Slide 93 text

【B】Parallel Routes のバグが解消 【3】Server Action に関する近況アップデート ■ Parallel Routes モーダル内の Server Action バグ ・ 実は、開いたモーダル内で「いいね」を押下するとクラッシュする ・ バグが修正されることを期待して、書籍サンプルはそのままとした

Slide 94

Slide 94 text

【B】Parallel Routes のバグが解消 【3】Server Action に関する近況アップデート ■ Parallel Routes モーダル内の Server Action バグ ・ 実は、開いたモーダル内で「いいね」を押下するとクラッシュする ・ バグが修正されることを期待して、書籍サンプルはそのままとした ・ v14.2.2 現在、このバグは解消

Slide 95

Slide 95 text

すでにリポジトリをクローンされた方は、 pull & 再インストールをお願いします ■ Parallel Routes モーダル内の Server Action バグ ・ 実は、開いたモーダル内で「いいね」を押下するとクラッシュする ・ バグが修正されることを期待して、書籍サンプルはそのままとした ・ v14.2.2 現在、このバグは解消 【B】Parallel Routes のバグが解消 【3】Server Action に関する近況アップデート

Slide 96

Slide 96 text

■ Server Action 使用(関連機能)は以前より安定してきている Server Action 使用は以前より安定 【3】Server Action に関する近況アップデート

Slide 97

Slide 97 text

■ Server Action 使用(関連機能)は以前より安定してきている ■ Progressive Enhancement はベストエフォートではある Server Action 使用は以前より安定 【3】Server Action に関する近況アップデート

Slide 98

Slide 98 text

Server Action を使用できるなら、Progressive Enhancement に挑戦してみても良いかもしれない ■ Server Action 使用(関連機能)は以前より安定してきている ■ Progressive Enhancement はベストエフォートではある Server Action 使用は以前より安定 【3】Server Action に関する近況アップデート

Slide 99

Slide 99 text

ご清聴ありがとうございました