Closed6

Server Actionsの引数の拡張

motoimotoi

Next.js、App RouterのServer Actionsでform内でsubmitされた値はformDataに値が格納されているが、それ以外に引数を渡したい場合が往々にしてある。その際のTips。

motoimotoi

①inputのtypeをhiddenにして、formDataに渡す。

無駄なDOMの記述は増えるが、formDataに値を集約することができる。fomrDataに対して、例えばzodでバリデーションするとして、当然その値も対象に含めることが容易にできる。

motoimotoi

②bindを使って引数を拡張する。

公式の例。

import { updateUser } from './actions'
 
export function UserProfile({ userId }: { userId: string }) {
  const updateUserWithId = updateUser.bind(null, userId)
 
  return (
    <form action={updateUserWithId}>
      <input type="text" name="name" />
      <button type="submit">Update User Name</button>
    </form>
  )
}

上記のようにすると、updateUserメソッドの引数は、

export const updateUser = (userId: string, formData: FormData) => {
...
}

のように拡張される。

motoimotoi

公式にも書いてある通り、基本②の方法を使うのがよさそう。
公式の例はClient Componentだが、Server Componentでもbindは使える。

motoimotoi

複数拡張したい時も使える。

import { updateUser } from './actions'
 
export function UserProfile({ userId }: { userId: string }) {
  const updateUserWithId = updateUser.bind(null, userId, teamId)
 
  return (
    <form action={updateUserWithId}>
      <input type="text" name="name" />
      <button type="submit">Update User Name</button>
    </form>
  )
}

なら、

export const updateUser = (userId: string, teamId: string, formData: FormData) => {
...
}

となる。

motoimotoi

まあでも、複数の値で拡張したい時は、オブジェクト1つを渡すのが管理がラク。

import { updateUser } from './actions'
 
export function UserProfile({ userId }: { userId: string }) {
  const updateUserWithId = updateUser.bind(null, { userId, userName, teamId, teamName })
 
  return (
    <form action={updateUserWithId}>
      <input type="text" name="name" />
      <button type="submit">Update User Name</button>
    </form>
  )
}
type Props = {
  userId: string
  userName: string
  teamId: string
  teamName: string
}

export const updateUser = ({ userId, userName, teamId, teamName }: Props, formData: FormData) => {
...
}
このスクラップは3日前にクローズされました