Closed6
Server Actionsの引数の拡張
Next.js、App RouterのServer Actionsでform内でsubmitされた値はformDataに値が格納されているが、それ以外に引数を渡したい場合が往々にしてある。その際のTips。
①inputのtypeをhiddenにして、formDataに渡す。
無駄なDOMの記述は増えるが、formDataに値を集約することができる。fomrDataに対して、例えばzodでバリデーションするとして、当然その値も対象に含めることが容易にできる。
②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) => {
...
}
のように拡張される。
公式にも書いてある通り、基本②の方法を使うのがよさそう。
公式の例はClient Componentだが、Server Componentでもbindは使える。
複数拡張したい時も使える。
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) => {
...
}
となる。
まあでも、複数の値で拡張したい時は、オブジェクト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日前にクローズされました