오늘은 React를 사용하여 구현한 로그인 컴포넌트에 대해 살펴보겠다. 이 컴포넌트는 회원가입, 로그인, 로그아웃 기능을 모두 포함하고 있어 실제 애플리케이션에서 활용도가 높을 것이다! 다만 supabase 연결하기 전 단계라 데이터 저장은 안된다는 제약이 있다.
1. 현재 구현 상태
현재 이 로그인 컴포넌트는 프론트엔드 로직만을 구현한 상태이다. 실제 데이터베이스나 인증 서비스와의 연동은 아직 이루어지지 않았다. 대신 setTimout을 사용하여 비동기 작업을 시뮬레이션하고 있다.
const handleSubmit = (e, action) => {
e.preventDefault();
setLoading(true);
setTimeout(() => {
setLoading(false);
if (action === "signup") {
alert("회원가입이 완료되었습니다");
} else if (action === "login") {
setIsLoggedIn(true);
alert("로그인이 완료되었습니다");
}
}, 1000);
};
이러한 접근 방식은 실제 백엔드 연동없이도 UI 흐름과 사용자 경험을 테스트할 수 있게 해준다!
2. 상태 관리
컴포넌트는 useState 훅을 사용하여 여러 상태를 관리한다.
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [loading, setLoading] = useState(false);
const [form, setForm] = useState({
email: "",
id: "",
password: "",
});
- isLoggedIn: 사용자의 로그인 상태를 추적
- loading: 비동기 작업 중 로딩 상태를 관리
- form: 사용자 입력 데이터를 저장
3. 이벤트 핸들링
- 입력 변경 처리: handleChange 함수는 폼 입력값의 변경을 실시간으로 처리한다.
const handleChange = (e) => {
setForm({ ...form, [e.target.name]: e.target.value });
console.log(form);
};
이 함수는 스프레드 연산자를 사용하여 기존 form 상태를 복사하고, 변경된 필드만 업데이트 한다.
- 폼 제출 처리: handleSubmit 함수는 회원가입과 로그인 모두에 사용된다.
const handleSubmit = (e, action) => {
e.preventDefault();
setLoading(true);
setTimeout(() => {
setLoading(false);
if (action === "signup") {
alert("회원가입이 완료되었습니다");
} else if (action === "login") {
setIsLoggedIn(true);
alert("로그인이 완료되었습니다");
}
}, 1000);
};
이 함수는 비동기 작업을 시뮬레이션 하기 위해 setTimeout을 사용한다. 실제 애플리케이션에서는 이 부분을 API 호출로 대체해야 한다.
- 로그아웃 처리: handleLogout 함수는 로그아웃 프로세스를 처리한다.
const handleLogout = () => {
setLoading(true);
setTimeout(() => {
setLoading(false);
setIsLoggedIn(false);
alert("로그아웃 되었습니다");
}, 1000);
};
- UI 렌더링: 컴포넌트 UI는 isLoggedIn 상태에 따라 조건부로 렌더링된다.
return (
<div>
{!isLoggedIn ? (
<>
<h1>회원가입</h1>
<form
className="input-container"
onSubmit={(e) => handleSubmit(e, "signup")}
>
<input
type="emial"
name="email"
placeholder="Your email"
value={form.email}
onChange={handleChange}
/>
<input
type="text"
name="id"
placeholder="ID"
value={form.id}
onChange={handleChange}
/>
<input
type="password"
name="password"
placeholder="PW"
value={form.password}
onChange={handleChange}
/>
<div>
<button
type="submit"
disabled={loading || !form.email || !form.id || !form.password}
>
{loading ? "처리중..." : "회원가입"}
</button>
</div>
</form>
<h1>로그인</h1>
<form
className="input-container"
onSubmit={(e) => handleSubmit(e, "login")}
>
<input
type="text"
name="id"
placeholder="ID"
value={form.id}
onChange={handleChange}
/>
<input
type="password"
name="password"
placeholder="PW"
value={form.password}
onChange={handleChange}
/>
<div>
<button
type="submit"
disabled={loading || !form.id || !form.password}
>
{loading ? "처리중..." : "로그인"}
</button>
</div>
</form>
</>
) : (
<div className="logout-input-container">
<button onClick={handleLogout} disabled={loading}>
{loading ? "처리중..." : "로그아웃"}
</button>
</div>
)}
<div className="login-or-not">
<p>{isLoggedIn ? "로그인 성공" : "로그아웃 상태"}</p>
</div>
</div>
);
};
- 로그아웃 상태: 회원가입 폼과 로그인 폼 표시
- 로그인 상태: 로그아웃 버튼만 표시
또한, 로딩 상태에 따라 버튼의 텍스트가 변경되며, 폼 입력값의 유효성에 따라 버튼의 활성화/비활성화가 결정된다. 여기에서는 disabled와 삼항연산자를 사용해주었다.
.
.
.
🚀🌈 앞으로의 계획: Supabase를 통한 완벽한 로그인 기능 구현
'개인과제' 카테고리의 다른 글
MBTI test(트러블 슈팅2🌟) (0) | 2024.09.10 |
---|---|
MBTI test(트러블 슈팅1🌟) (0) | 2024.09.10 |
리액트로 만든 나만의 포켓몬 도감: 일주일간의 도전과 성장 (4) | 2024.08.26 |
Redux 사용해서 TodoList 만들기! (0) | 2024.08.22 |
Context API로 Props Drilling 해결하기 (0) | 2024.08.21 |