大数据

useActionState案例

/src/app/user/[userId]/page.tsx

服务端组件根据路由动态传参将userId传给客户端组件

import {UserProfile} from "@/components/user-profile";

export default async function Page({params}: { params: Promise<{ userId: string }> }) {
    const {userId} = await params
    return (
        <UserProfile userId={userId}/>
    )
}

/src/components/user-profile.tsx

客户端组件将userId绑定到server action:updateUser

'use client'

import { updateUser, FormState } from '@/app/actions'
import { useActionState } from "react";

export function UserProfile({ userId }: { userId: string }) {
    const updateUserWithId = updateUser.bind(null, userId);

    const initialState: FormState = {
        message: "",
    };

    const [state, formAction, pending] = useActionState<FormState, FormData>(
        updateUserWithId,
        initialState
    );

    return (
        <form action={formAction}>
            <input type="text" name="name"/>
            <p aria-live="polite">{state?.message}</p>
            <button type="submit" disabled={pending}>Update User Name</button>
        </form>
    )
}

/src/app/actions.ts

因为自定义了userId同时还要接受useActionState传参,第一个参数是 自定义的userId,后面才是useActionState的传参,最后是FormData

"use server"

export type FormState = {
    message: string;
};

export async function updateUser(
    userId: string,
    prevState: FormState,
    formData: FormData
): Promise<FormState> {
    console.log(userId, formData);
    return { message: "Updated successfully" };
}

这里action返回值会传给下面的state

const [state, formAction, pending] = useActionState<FormState, FormData>(
        updateUserWithId,
        initialState
    );

后续调用:{state?.message}

绑定userId写法也可以这样写:

const updateUserWithId = async (prevState: FormState, formData: FormData) => {
    return updateUser(prevState, userId, formData);
  };

这么写可以自定义updateUser的参数顺序,对应以上写法,updateUser需要改写如下:

export async function updateUser(
    prevState: FormState,
    userId: string,
    formData: FormData
): Promise<FormState> {
    console.log(userId, formData);
    return { message: "Updated successfully" };
}

也就是useActionState还是给updateUserWithId函数传参(prevState: FormState, formData: FormData) 第一个还是prevState,只是实际我们调用的updateUser参数顺序是按照我们自己的来定义。