회원가입 폼 만들기

사용자의 이메일과 비밀번호를 입력받을 회원가입 폼을 만들어 보겠습니다.

컨테이너 추가하기

Change indicator src/containers/Signup.tsx에 새로운 컨테이너를 생성하고 다음 내용을 추가합니다.

import React, { useState } from "react";
import Form from "react-bootstrap/Form";
import Stack from "react-bootstrap/Stack";
import { useNavigate } from "react-router-dom";
import { useFormFields } from "../lib/hooksLib";
import { useAppContext } from "../lib/contextLib";
import LoaderButton from "../components/LoaderButton";
import "./Signup.css";

export default function Signup() {
  const [fields, handleFieldChange] = useFormFields({
    email: "",
    password: "",
    confirmPassword: "",
    confirmationCode: "",
  });
  const nav = useNavigate();
  const { userHasAuthenticated } = useAppContext();
  const [isLoading, setIsLoading] = useState(false);
  const [newUser, setNewUser] = useState<null | string>(null);

  function validateForm() {
    return (
      fields.email.length > 0 &&
      fields.password.length > 0 &&
      fields.password === fields.confirmPassword
    );
  }

  function validateConfirmationForm() {
    return fields.confirmationCode.length > 0;
  }

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setIsLoading(true);
    setNewUser("test");
    setIsLoading(false);
  }

  async function handleConfirmationSubmit(
    event: React.FormEvent<HTMLFormElement>
  ) {
    event.preventDefault();
    setIsLoading(true);
  }

  function renderConfirmationForm() {
    return (
      <Form onSubmit={handleConfirmationSubmit}>
        <Stack gap={3}>
          <Form.Group controlId="confirmationCode">
            <Form.Label>Confirmation Code</Form.Label>
            <Form.Control
              size="lg"
              autoFocus
              type="tel"
              onChange={handleFieldChange}
              value={fields.confirmationCode}
            />
            <Form.Text muted>Please check your email for the code.</Form.Text>
          </Form.Group>
          <LoaderButton
            size="lg"
            type="submit"
            variant="success"
            isLoading={isLoading}
            disabled={!validateConfirmationForm()}
          >
            Verify
          </LoaderButton>
        </Stack>
      </Form>
    );
  }

  function renderForm() {
    return (
      <Form onSubmit={handleSubmit}>
        <Stack gap={3}>
          <Form.Group controlId="email">
            <Form.Label>Email</Form.Label>
            <Form.Control
              size="lg"
              autoFocus
              type="email"
              value={fields.email}
              onChange={handleFieldChange}
            />
          </Form.Group>
          <Form.Group controlId="password">
            <Form.Label>Password</Form.Label>
            <Form.Control
              size="lg"
              type="password"
              value={fields.password}
              onChange={handleFieldChange}
            />
          </Form.Group>
          <Form.Group controlId="confirmPassword">
            <Form.Label>Confirm Password</Form.Label>
            <Form.Control
              size="lg"
              type="password"
              onChange={handleFieldChange}
              value={fields.confirmPassword}
            />
          </Form.Group>
          <LoaderButton
            size="lg"
            type="submit"
            variant="success"
            isLoading={isLoading}
            disabled={!validateForm()}
          >
            Signup
          </LoaderButton>
        </Stack>
      </Form>
    );
  }

  return (
    <div className="Signup">
      {newUser === null ? renderForm() : renderConfirmationForm()}
    </div>
  );
}

여기서 하는 작업 대부분은 상당히 직관적이지만, 간단히 살펴보겠습니다.

  1. 사용자에게 확인 코드를 입력할 폼을 보여주기 위해, 사용자 객체가 있는지 여부에 따라 두 가지 폼을 조건부로 렌더링합니다.

    {
      newUser === null ? renderForm() : renderConfirmationForm();
    }
    
  2. 이전에 만든 LoaderButton 컴포넌트를 제출 버튼으로 사용합니다.

  3. 두 개의 폼이 있기 때문에 validateFormvalidateConfirmationForm이라는 두 가지 유효성 검사 함수가 있습니다.

  4. 이메일과 확인 코드 필드에 autoFocus 플래그를 설정합니다.

    <Form.Control autoFocus type="email" ... />

  5. 현재 handleSubmithandleConfirmationSubmitisLoading 상태를 설정하고 newUser 상태에 더미 값을 설정하는 것 외에는 별다른 작업을 하지 않습니다.

  6. 그리고 폼 필드를 처리하기 위해 이전에 생성한 useFormFields 커스텀 React Hook을 사용합니다.

    const [fields, handleFieldChange] = useFormFields({
      email: "",
      password: "",
      confirmPassword: "",
      confirmationCode: "",
    });
    

Change indicator 또한 src/containers/Signup.css에 몇 가지 스타일을 추가합니다.

@media all and (min-width: 480px) {
  .Signup {
    padding: 60px 0;
  }

  .Signup form {
    margin: 0 auto;
    max-width: 320px;
  }
}

라우트 추가하기

Change indicator 마지막으로, src/Routes.tsx 파일에서 로그인 라우트 아래에 우리의 컨테이너를 라우트로 추가합니다.

<Route path="/signup" element={<Signup />} />

Change indicator 그리고 헤더에 컴포넌트를 포함시킵니다.

import Signup from "./containers/Signup.tsx";

이제 브라우저로 전환하여 회원가입 페이지로 이동하면 새로 생성한 폼을 볼 수 있습니다. 폼은 정보를 입력해도 아직 아무런 동작을 하지 않지만, 이메일 주소, 비밀번호, 비밀번호 확인을 입력해 볼 수 있습니다.

회원가입 페이지 추가 스크린샷

그런 다음, 제출 버튼을 누르면 확인 코드 폼이 나타납니다. 이는 우리가 Cognito에 연결했을 때 폼이 어떻게 동작할지에 대한 아이디어를 제공합니다.

회원가입 페이지 확인 코드 스크린샷

다음으로, 회원가입 폼을 Amazon Cognito에 연결해 보겠습니다.