TIL #35 React 뉴스피드 프로젝트-2 로그인 페이지

DO YEON KIM·2024년 6월 4일
1

부트캠프

목록 보기
35/72

하루 하나씩 작성하는 TIL #35


이번 til에선 로그인 기능 코드를 뜯어서 설명하겠다.


import { useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import SignInBtn from '../components/SignInBtn';
import { supabase } from '../supabaseClient';

function LogIn() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const navigate = useNavigate();

  const handleSignIn = async (e) => {
    e.preventDefault();

    const { error } = await supabase.auth.signInWithPassword({
      email,
      password,
    });

    if (error) {
      setError('이메일 또는 비밀번호가 올바르지 않습니다.');
    } else {
      setError('');
      alert('로그인되었습니다.');
      setEmail('');
      setPassword('');
      navigate('/'); // 로그인 성공 시 홈페이지로 이동
    }
  };

  return (
    <div className="relative min-h-screen bg-gray-100">
    <main className="flex flex-col items-center justify-center min-h-screen pt-20">
      <div className="bg-white p-10 rounded shadow-md w-full max-w-md mt-8">
        <h1 className="text-5xl font-bold mb-6 text-center">L O G I N</h1>
        <form onSubmit={handleSignIn} className="space-y-6">
          <div>
            <label className="block text-lg text-gray-700">이메일 :</label>
            <input
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder="이메일을 입력하세요"
              required
              className="w-full px-4 py-3 border rounded text-lg"
            />
          </div>
          <div>
            <label className="block text-lg text-gray-700">비밀번호 :</label>
            <input
              type="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              placeholder="비밀번호를 입력하세요"
              required
              className="w-full px-4 py-3 border rounded text-lg"
            />
          </div>
          <button type="submit" className="w-full bg-blue-500 text-white py-3 rounded text-lg hover:bg-blue-600">
            로그인
          </button>
        </form>
        <p className="mt-6 text-center text-lg">
          아직 회원이 아니라면?{' '}
          <Link to="/sign_up" className="text-blue-500 hover:underline">
            가입하러 가기
          </Link>
        </p>
        <div className="mt-6 flex justify-center w-full">
          <SignInBtn />
        </div>
        {error && <p className="mt-6 text-red-500 text-center text-lg">{error}</p>}
      </div>
    </main>
  </div>
  );
}

export default LogIn;

이 코드를 하나하나 뜯어서 설명해보고자한다. 일단 출력 결과는

위와 같다.


1.

  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const navigate = useNavigate();
  • useState훅을 사용하여 이메일과 패스워드를 받아 로그인+ 오류 저장을 하고 초기 값은 빈 문자열로 설정해준다.

  • useNavigate 훅을 사용하여 네비게이션을 관리한다. 이 훅은 사용자를 다른 경로로 리디렉션하거나 이동시킬 때 사용되는데, 본 프로젝트에서는 로그인 후 홈페이지로 이동하기 위해 사용됐다.


2.

  const handleSignIn = async (e) => {
    e.preventDefault();
    
    const { error } = await supabase.auth.signInWithPassword({
      email,
      password,
    });    
  • 로그인 폼이 제출될 때 새로고침되는 기본 동작을 막아준다.

  • async키워드는 함수가 비동기적으로 동작함을 나타낸다. 이 키워드가 함수 앞에 붙으면, 그 함수는 Promise를 반환하게 된다.

  • ex) 네트워크 요청을 보내거나 파일을 읽어올 때는 결과가 즉시 사용 가능하지 않은데, 이때 에이싱크 키워드를 사용하여 비동기 작업을 실행할 수 있다.

  • handleSignIn 함수에서 async 키워드를 사용하는 이유는 supabase.auth.signInWithPassword() 메서드가 비동기 함수이기 때문이다. 이 메서드는 Supabase 서버에 로그인 요청을 보내고, 그 결과를 반환하기 위해 시간이 필요하기 때문에 async 키워드를 사용하여 이 함수를 비동기적으로 호출하고, 그 결과를 기다리는 것.

위 코드는 수퍼베이스 Docs에서 찾아볼 수있다.


3.

    if (error) {
      setError('이메일 또는 비밀번호가 올바르지 않습니다.');
    } else {
      setError('');
      alert('로그인되었습니다.');
      setEmail('');
      setPassword('');
      navigate('/'); // 로그인 성공 시 홈페이지로 이동
    }
  };

navigate 함수를 사용하여 사용자를 홈페이지로 리디렉션한다. 이는 로그인 성공 후 사용자를 메인 페이지로 이동시키는 역할을 한다.


4.

 <input
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder="이메일을 입력하세요"
              required
              className="w-full px-4 py-3 border rounded text-lg"
            />
  • onChange={(e) => setEmail(e.target.value)}는 필드이 값이 변경될 때마다 호출된다. 입력 필드 전체의 값을 email 상태 변수로 업데이트 해준다. 이로 인해 react는 입력 필드의 값이 변경될 때마다 컴포넌트의 상태를 업데이트하고 다시 렌더링해준다.
  • required 속성은 입력 필드를 필수 항목으로 지정한다.

기타 버튼 및 회원가입 페이지는 다음 til에서 작성하겠다.

profile
프론트엔드 개발자를 향해서

0개의 댓글