ShotaroHirose59 / nextjs-dashboard

Learn Next.js
https://nextjs-dashboard-dun-pi-28.vercel.app
0 stars 0 forks source link

Chapter12 Mutating Data #19

Open ShotaroHirose59 opened 6 months ago

ShotaroHirose59 commented 6 months ago

In the previous chapter, you implemented search and pagination using URL Search Params and Next.js APIs. Let's continue working on the Invoices page by adding the ability to create, update, and delete invoices! https://nextjs.org/learn/dashboard-app/mutating-data

Topics

ShotaroHirose59 commented 6 months ago

サーバーアクションとは?

React Server Actions を使用すると、サーバー上で非同期コードを直接実行できます。データを変更するために API エンドポイントを作成する必要がなくなります。代わりに、サーバー上で実行され、クライアント コンポーネントまたはサーバー コンポーネントから呼び出すことができる非同期関数を作成します。

--> Web アプリケーションはさまざまな脅威に対して脆弱になる可能性があるため、セキュリティは最優先事項です。ここでサーバー アクションが登場します。サーバー アクションは、さまざまな種類の攻撃から保護し、データを保護し、承認されたアクセスを保証する、効果的なセキュリティ ソリューションを提供します。サーバー アクションは、POST リクエスト、暗号化されたクロージャ、厳格な入力チェック、エラー メッセージのハッシュ化、ホスト制限などの技術を通じてこれを実現し、すべて連携してアプリの安全性を大幅に強化します。

サーバーアクションでのフォームの使用

// Server Component
export default function Page() {
  // Action
  async function create(formData: FormData) {
    'use server';

    // Logic to mutate data...
  }

  // Invoke the action using the "action" attribute
  return <form action={create}>...</form>;
}

<form>要素のaction属性を使ってアクションを呼び出すことができる。 アクションは自動的に、取り込まれたデータを含むネイティブの FormData オブジェクトを受け取る。

progressive enhancement

クライアントでJSが無効になっていもFormは動作する

Next.js with Server Actions

サーバーアクションはNext.jsのキャッシュとも深く統合されています。サーバーアクションでフォームが送信されると、アクションを使用してデータを変更できるだけでなく、revalidatePathやrevalidateTagなどのAPIを使用して、関連するキャッシュを再検証することもできます。

ShotaroHirose59 commented 6 months ago

2. Create a Server Action

Good to know

HTMLでは、action属性にURLを渡します。このURLは、フォームデータの送信先(通常はAPIエンドポイント)になります。 しかしReactでは、action属性は特別なpropとみなされます。つまり、Reactはアクションを呼び出すことができるように、action属性の上に構築します。 裏では、Server ActionsはPOST APIエンドポイントを作成します。これが、Server Actionsを使用する際にAPIエンドポイントを手動で作成する必要がない理由です。

ShotaroHirose59 commented 6 months ago

4. Pass the id to the Server Action

Server Actionにidを直接引数として渡すことはできない。

// Passing an id as argument won't work
<form action={updateInvoice(id)}>

代わりにJS bindを使用してidをServer Actionに渡す。

const updateInvoiceWithId = updateInvoice.bind(null, invoice.id);

return (
  <form action={updateInvoiceWithId}>

Deleting an invoice

削除ボタンを

要素で囲み、bindを使ってidをServer Actionに渡す。

import { deleteInvoice } from '@/app/lib/actions';

// ...

export function DeleteInvoice({ id }: { id: string }) {
  const deleteInvoiceWithId = deleteInvoice.bind(null, id);

  return (
    <form action={deleteInvoiceWithId}>
      <button className="rounded-md border p-2 hover:bg-gray-100">
        <span className="sr-only">Delete</span>
        <TrashIcon className="w-4" />
      </button>
    </form>
  );
}
ShotaroHirose59 commented 6 months ago

あとで見る How to Think About Security in Next.js https://nextjs.org/blog/security-nextjs-server-components-actions