非同期データ変更と処理は、モダンなウェブアプリケーションで必要な任务です。サーバーで独立した非同期関数を実行し、データストアにデータを保存、電子メールを送信、PDFをダウンロード、画像を処理などの任务を実行することがあります。
Next.jsは、Server Actions
を提供してくれます。これらは、サーバー上で実行される非同期関数であり、私たちは、サーバー上でのデータ変更などにserver actionsを使用することができます。しかし、server actionsは、サーバーおよびクライアントコンポーネントから呼び出すことができます。
Server actionsは、フォームのデータが送信されたときにアクションを実行することで、フォームの送信を処理するのに優れた方法です。この記事で、Next.jsのserver actionsで追加の引数を処理する実用的な使用例について見ていきましょう。
Next.jsのServer Actionsをデザインパターンとプロジェクト構築について学ぶことに興味を持つという場合、私はあなたに対するクラッシュコースを作成しました。ここから
また、この記事はビデオチュータリアルとしてここで見ることができます。
目次
追加の引数を渡す必要性とは?
フォームの送信時にサーバーのアクションを実行する場合、サーバーのアクションは自動的にフォームのデータを取得する。たとえば以下のフォームを見てください。
<form className="p-4 flex" action={updateUser}>
<Input className="w-1/2 mx-2" type="text" name="name" />
<Button type="submit">Update User Name</Button>
</form>
ここで、フォームが送信されると updateUser
というサーバーアクションが実行されます。updateUser
関数は送信されたフォームデータを引数として受け取り、これを使ってフォームのフィールド値を抽出することができます。
以下のコードスニペットで、updateUser
関数は formData
を引数として受け取り、そこから name
フィールドの値を抽出することができます。
"use server"
export async function updateUser(formData) {
const name = formData.get('name');
console.log(name);
}
このパターンはほとんどの基本的な使用事例をカバーしていますが、プログラム的に追加の引数をサーバーのアクションに渡す必要がある場合があります。これらの引数はフォームやフォームデータ、ユーザーの入力データの一部ではありません。これらはプログラム的に渡される値であり、サーバーのアクションに追加の計算を行うために使用されます。
これについて理解するために、以下のサーバーアクションのコードスニペットをご確認ください。これは以前に見たものと同じサーバーアクションですが、通常のformData
引数とともにuserId
追加引数を渡しています。
"use server"
export async function updateUser(userId, formData) {
const name = formData.get('name');
console.log(userId);
console.log(name);
}
userId
の値はアプリの内部のものです。この値をフォーム送信の一部として用户提供する必要はないです。代わりに、追加の計算を行うためにプログラム的にサーバーアクションに渡す必要がある場合があります。
正しいのは私たちが話している用途です。私たちがなぜ必要だと理解したので、どのように実現するかを理解しましょう。まずは、表单とそれに対応する機能のあるサーバーアクションを作成しましょう。
サーバーアクションによる表单
Next.jsアプリケーションのapp
ディレクトリー下面にactions
ディレクトリーを作成します。そして、actions
フォルダーに以下のコードのuser.js
ファイルを作成します。
"use server"
export async function updateUser(formData) {
const name = formData.get('name');
console.log(name);
// 名前を何でもして、DBに保存し、請求書を作成してください!
}
これがNext.jsでサーバー機能を作成する方法です。ファイルの先頭に”use server”
ディレクティブを追加して、Next.jsにこれが特別なファイルで、1つ以上の非同期関数をサーバー上で実行することを示してください。
次に、サーバーのアクション(非同期関数)updateUser
をformData
を引数として使用しています。関数定義の内部で、name
の値を抽出し、コンソールに出力します。
次に、このサーバーのアクションをフォームに結合しましょう。これを行うために、プロジェクトのルートフォルダー下にcomponents
というフォルダーを作成し、次のコードを持つuser-form.jsx
というファイルを作成します。
import { Input } from "./ui/input"
import { Button } from "./ui/button"
import { updateUser } from "@/app/actions/user"
const UserForm = () => {
return(
<form className="p-4 flex" action={updateUser}>
<Input className="w-1/2 mx-2" type="text" name="name" />
<Button type="submit">Update User Name</Button>
</form>
)
}
export default UserForm;
これは、単純なReactコンポーネントで、フォームがあります。このフォームには、name
という名前の入力テキストフィールドと、フォームを送信するための送信按钮が含まれています。このフォームにはaction
属性があり、updateUser
というサーバーアクションを値として含まれています。今度、フォームがname
の値で送信されると、先程述べたように、サーバーアクションはフォームデータの一部として取得します。
試すために、Next.jsのルートとページを作成し、UserForm
コンポーネントを使用できるようにしましょう。app
ディレクトリー下にextra-args
というフォルダーを作成し、app/extra-args
ディレクトリー下に次のコードを持つpage.js
というファイルを作成します。
import UserForm from "@/components/user-form";
const ExtraArgsDemo = () => {
return (
<UserForm />
)
}
export default ExtraArgsDemo;
これは、単純なReactコンポーネントです。ここにUserForm
コンポーネントをインポートし、JSX内で使用しています。今、ローカルサーバーを実行し、このルートlocalhost:3000/extra-args
にアクセスしてください。テキストフィールドとボタンのあるフォームを表示されるはずです。
テキストフィールドにテキストを入力し、ボタンをクリックしてください。
現在、打ち込んだテキストがサーバーコンソールに印刷されていることがわかります。なぜサーバーコンソールにですか?ブラウザーコンソールにはなぜですか?これはサーバー上でのアクションがクライアントサイドのブラウザー上ではなく、サーバー上で実行されるからです。
これにより、次のようなデータフローを Establish しました。
Page => Form => Server Action
ページにはフォームがあり、フォームは送信時にサーバーアクションを実行します。サーバーアクションはサーバーコンソールにフォームデータを印刷します。
これから、これらの部材を強化し、サーバーアクションに追加の引数を渡すことです。
追加の引数を渡す方法
PageからUserForm
コンポーネントにuserId
を渡す。このuserId
の値を Pretend して、このuserIdをプログラム的に私たちのフォームやサーバーアクションに渡すことをします。
import UserForm from "@/components/user-form";
const ExtraArgsDemo = () => {
return (
<UserForm userId={"1234"} />
)
}
export default ExtraArgsDemo;
在UserForm
コンポーネントでuserId
のプロパティを受け取ります。今、このuserId
をupdateUser
サーバーアクションに渡すために特別なことをしなければなりません。
JavaScriptにはbind()
と呼ばれる魔法的な方法があり、これは部分的に適用された関数
(Partially Applied Function)を作成することを助けます。この部分的に適用された関数を使用して、他の関数の既定の引数から関数を作成することができます。
私たちの場合、updateUser
関数にはすでに formData
という引数があります。ここで、bind()
メソッドを使って追加の引数として userId
を渡し、新しい関数を作成できます。
const updatedUserWithId = updateUser.bind(null, userId);
bind()
メソッドの最初の引数は、関数をバインドするコンテキストです。このコンテキストは、this
キーワードの値との関連付けを処理します。私たちの場合、それを変更しないので null
のままにしておくことができます。その後、新しい引数 userId
を渡しました。bind()
メソッドはサーバーとクライアントの両方のコンポーネントで機能することを知っておくと良いでしょう。
ここで変更された UserForm
コンポーネント(user-form.jsx
ファイル)を示します。フォームアクションの値は、新しい関数 updatedUserWithId
に変更されていることに注意してください。
import { Input } from "./ui/input"
import { Button } from "./ui/button"
import { updateUser } from "@/app/actions/user"
const UserForm = ({userId}) => {
const updatedUserWithId = updateUser.bind(null, userId);
return(
<form className="p-4 flex" action={updatedUserWithId}>
<Input className="w-1/2 mx-2" type="text" name="name" />
<Button type="submit">Update User Name</Button>
</form>
)
}
export default UserForm;
これで、サーバーアクションは引数として userId
の値を受け取ります。それをコンソールに出力してみましょう。
"use server"
export async function updateUser(userId, formData) {
const name = formData.get('name');
console.log(userId);
console.log(name);
// ユーザーIDと名前で何かを行い、DBに保存し、
// 請求書を作成するなど!
}
名前の値を入力してフォームを送信すると:
userId と名前の値が両方ともサーバーコンソールに記録されているのがわかります。素晴らしいですね!フォームデータから一つの値を記録し、もう一つは内部的にサーバーアクションに渡されました。
このようにして、フォームデータと一緒に追加の引数をサーバーアクションに渡す方法を学びました。
隠しフィールドはどうでしょうか?
HTMLは、ユーザーからの入力を受け付けずにクライアントのデータをサーバーに送るための隐しタイプのフォームフィールドをサポートしています。つまり、私たちはuserId
の値を次のように隐しフィールドを使用して送信することができます。
ですので、なぜ私たちはbind()
メソッドを使ってこれらの操作を行ったのでしょうか。というのも、安全性の疑念に基づいています。隐しフィールドを使用してデータを渡す場合、値はレンダrized HTMLの一部になり、エンコードされないため、プログラム的に处理する方がよいです。
リソース
今回の記事はここで終わります。この記事を読んでおり、新しいことを学びましたか?そうであれば、コンテンツが有益か否か知りたいです。私は、この記事で使用した全てのソースコードが GitHubにあります。
-
この記事で使用した全てのソースコードは GitHubにあります。
-
もっと読む場合は、サーバーアクション公式ドキュメントがあります。
-
また、bind()メソッドについてもここで詳細に読むことができます。
さらに、私とコミュニケートすることができます:
-
私のYouTubeチャンネルを購読してください。
React
とそのエコシステム、Next.js
を学びたいと思う方、 fundamentalsとプロジェクトを含むYouTubeチャンネル上のプレイリストをご覧ください。まだ25本以上のビデオチュートリアルと15時間以上の魅力的なコンテンツがあります。無料です。お気に召しますか? -
日々のスキルアップのヒントを見逃したくない場合は、X(Twitter)またはLinkedInでフォローしてください。
-
GitHubで私のオープンソースの取り組みをチェックしてフォローすることもおすすめです。
-
私は定期的に、GreenRoots Blogに意味深い投稿を発表しています。おそらく、それらはあなたにも有益かもしれません。
次の記事で再会します。そのまま、自分自身に注意を払い、学び続けてください。
Source:
https://www.freecodecamp.org/news/how-to-pass-additional-arguments-to-nextjs-server-actions/