본 글에서는 인증 작업 생성과 사용자 유효성 검증에 대한 코드를 소개하고, 해당 코드를 구성하는 각 요소와 구현 방법을 설명하겠습니다.
인증 작업 생성을 위한 코드는 주로 AuthForm 컴포넌트와 action 함수를 포함합니다. AuthForm 컴포넌트는 사용자 인터페이스(UI)를 담당하며, action 함수는 인증 작업에 대한 로직을 처리합니다.
import AuthForm from '../components/AuthForm';
import { json, redirect } from 'react-router-dom';
function AuthenticationPage() {
return <AuthForm />;
}
export default AuthenticationPage;
export const action = async ({request, params}) => {
const mode = new URL(request.url).searchParams.get('mode') || 'login';
if(mode !== 'login' && mode !== 'signup'){
throw json({message: 'Invalid mode'}, {status: '422'});
}
const data = await request.formData();
const authData = {
email: data.get('email'),
password: data.get('password'),
}
const response = await fetch(`http://localhost:8080/${mode}`,{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(authData),
});
if(response.status === 422 || response.status === 401){
return response;
}
if(!response.ok){
throw json({message: 'Could not authenticate user.'}, {status: 500});
}
return redirect('/');
}
사용자 유효성 검증을 위한 코드는 AuthForm 함수 내에서 처리됩니다. 이 함수는 React hooks를 사용하여 검증 결과를 저장하고, 검증 에러와 메시지를 출력합니다.
검증 에러와 메시지는 <ul>
태그와 <p>
태그를 사용하여 출력합니다. 각 에러는 <li>
태그로 나타내며, 전체 메시지는 <p>
태그 안에 표시됩니다.
이메일과 비밀번호를 입력받기 위해 <input>
태그를 사용합니다. 각각의 태그에는 id, type, name, 그리고 required 속성이 포함되어 있습니다.
로그인 및 회원가입 버튼은 <Link>
컴포넌트와 <button>
태그를 사용하여 구현합니다. <Link>
컴포넌트는 현재 페이지의 mode에 따라 로그인 또는 회원가입 페이지로 이동하며, <button>
태그는 폼 제출을 담당합니다
import { React } from "react";
import { Form, Link, useSearchParams, useActionData, useNavigation } from "react-router-dom";
import classes from "./AuthForm.module.css";
function AuthForm() {
const data = useActionData();
const navigation = useNavigation();
const [searchParams] = useSearchParams();
const isLogin = searchParams.get("mode") === "login";
const isSubmmiting = navigation.state === "submitting";
return (
<>
<Form method="post" className={classes.form}>
<h1>{isLogin ? "Log in" : "Create a new user"}</h1>
{data && data.errors && (
<ul>
{Object.values(data.errors).map((error, index) => (
<li key={index}>{error}</li>
))}
</ul>
)}
{data && data.message && <p>{data.message}</p>}
<p>
<label htmlFor="email">Email</label>
<input id="email" type="email" name="email" required />
</p>
<p>
<label htmlFor="image">Password</label>
<input id="password" type="password" name="password" required />
</p>
<div className={classes.actions}>
<Link to={`?mode=${isLogin ? "signup" : "login"}`}>{isLogin ? "Create new user" : "Login"}</Link>
<button disabled={isSubmmiting}>{isSubmmiting ? "Submitting" : "Save"}</button>
</div>
</Form>
</>
);
}
export default AuthForm;
서버와 통신하는 과정은 action 함수에서 처리됩니다. fetch 함수를 사용하여 서버와 통신하며, 서버로부터 받은 응답을 처리한 후 필요한 작업을 수행합니다.