ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Form에서 두개 이상의 버튼을 다루기 (feat. server action )
    FrontEnd/Next.js 2024. 6. 14. 20:03

    Form 안에 두개 이상의 버튼이 있을 경우 어떤 버튼을 클릭했는지에 따라 행하는 액션이 다를 수 있다.

    이 때 button의 name와 value 속성을 이용하면 form의 action에서 버튼의 주체를 파악할 수 있다.

    form action에서 넘겨주는 파라미터는 FormData로써 폼 안에 버튼을 클릭하면 해당하는 버튼의 name과 value 정보가 포함되어져 있다.

    (이 때 form 안에 input 필드가 있다면 input들의 name과 value들도 출력 됨.)

    import { signIn } from '@/auth';
    
    function SignIn() {
        const handleAction = async (data: FormData) => {
            'use server';
            console.log(data);
        };
        return (
            <form className="flex flex-col" action={handleAction}>
                <input
                    name="email"
                    className="border"
                    placeholder="asd"
                    type="text"
                />
                <button
                    className="bg-blue-400 px-4 py-1"
                    name="google"
                    type="submit"
                    value="google"
                >
                    Google
                </button>
                <button
                    className="bg-yellow-400 px-4 py-1"
                    name="kakaoa"
                    type="submit"
                    value="kakao"
                >
                    kakao
                </button>
            </form>
        );
    }
    
    export default SignIn;

    input 창에 qweqwe를 입력 후 구글 버튼을 클릭하면 아래와 같이 터미널에 출력됨(server action이므로)

    물론 카카오를 출력하면 아래와 같이 출력 됨.

    이 같은 결과들은 action을 실행하면 서버단으로 POST 메서드가 요청 되면서 

    POST /signIn?email=asdasd&kakaoa=kakao 

    와 같이 전송되기 때문이다.

    이제 구글 버튼을 클릭하면 구글로 , 카카오 클릭시 카카오로 인가를 요청할려면 

    버튼의 주체인 provider를 알기 위해 아래와 같이 코드를 짜준다.

    const provider = data.get('google') || data.get('kakaoa');

    이제 next-auth의 메서드 signIn에게 해당 provider를 넘겨주면 해당 provider의 로그인 페이지로 이동되면서 성공하면  인가코드를 받아오고 이를 통해 토큰들을 받아오는 oauth가 진행 됨.

    const handleAction = async (data: FormData) => {
            'use server';
    
            const provider = data.get('google') || data.get('kakaoa');
            if (provider) await signIn(provider as string);
    };

    아래는 전체 코드

    import { signIn } from '@/auth';
    
    function SignIn() {
        const handleAction = async (data: FormData) => {
            'use server';
    
            const provider = data.get('google') || data.get('kakaoa');
            if (provider) await signIn(provider as string);
        };
        return (
            <form className="flex flex-col" action={handleAction}>
                <input
                    name="email"
                    className="border"
                    placeholder="asd"
                    type="text"
                />
                <button
                    className="bg-blue-400 px-4 py-1"
                    name="google"
                    type="submit"
                    value="google"
                >
                    Google
                </button>
                <button
                    className="bg-yellow-400 px-4 py-1"
                    name="kakaoa"
                    type="submit"
                    value="kakao"
                >
                    kakao
                </button>
            </form>
        );
    }
    
    export default SignIn;

    참고 문서:

    https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations

Designed by Tistory.