📌 오늘 학습한 주제
- React Router Dom을 활용한 페이지 라우팅 및 상태 전달 (
useNavigate, useLocation)
- URL 매개변수 파싱 기법 (
useSearchParams, useParams)
- React
useState 기반 입력 폼 동기화 및 Axios 비동기 인증 통신 (EventPage.jsx)
- 웹 브라우저 저장소 (
localStorage)를 활용한 사용자 세션 관리
💡 오늘 배운 것 — 나만의 언어로
① 오늘의 목표
- React Router Dom의 주요 Hook들을 활용하여 로그인 인증 처리 및 상태/쿼리스트링/경로 파라미터를 동반한 페이지 전환(Transition) 흐름 구현하기
② 학습할 내용
- 상태 관리 및 비동기 로그인 인증 (
EventPage.jsx): useState로 이메일과 비밀번호 입력값을 관리하고, 로그인 버튼 클릭 시 Axios로 백엔드 API (/users?email=...&pswd=...) 조회를 수행했다. 인증 성공 시 localStorage에 사용자 정보를 저장하고 useNavigate의 state 옵션을 사용하여 성공 페이지로 이동시켰다.
- 성공 페이지 및 State 수신 (
SuccessPage.jsx): 라우터의 useLocation() Hook을 통해 전달받은 state 객체(user, from)와 localStorage에 저장된 사용자명을 조합하여 동적 안내 문구를 출력했다.
- 실패 페이지 및 QueryString 수신 (
ErrorPage.jsx): 로그인 실패 시 useSearchParams() Hook을 사용해 URL 쿼리스트링(?category=react&sort=latest) 파라미터 값을 파싱하고 안내 화면을 구성했다.
- 경로 파라미터 파싱 (
ViewPage.jsx): useParams() Hook을 활용해 URL Path Variable(/read/:id) 형태의 동적 id 값을 추출하는 방법을 학습했다.
💻 오늘 핵심 코드
1. 로그인 인증 및 페이지 전환 처리 (EventPage.jsx)
import Button from 'react-bootstrap/Button';
import 'bootstrap/dist/css/bootstrap.min.css';
import { useEffect, useState } from 'react';
import api from '../../api/axios';
import { useNavigate } from 'react-router-dom';
const EventPage = () => {
const [email, setEmail] = useState('');
const [pswd, setPswd] = useState('');
const moveUrl = useNavigate();
const signInHandler = async (e, email, pswd) => {
e.preventDefault();
await api.get(`/users?email=${email}&pswd=${pswd}`)
.then(response => {
const ary = response.data;
if (ary.length > 0) {
const user = ary[0];
localStorage.setItem('userName', user.name);
moveUrl('/success', {
state: { user, from: '/signIn' }
});
} else {
moveUrl('/error?category=react&sort=latest');
}
})
.catch(err => {
console.log(`debug >>>> error : `, err);
});
}
return (
<div className='container'>
<div className="mb-3 mt-3">
<label htmlFor="email" className="form-label">Email:</label>
<input
type="email"
className="form-control"
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="mb-3">
<label htmlFor="pwd" className="form-label">Password:</label>
<input
type="password"
className="form-control"
id="pwd"
value={pswd}
onChange={(e) => setPswd(e.target.value)}
/>
</div>
<Button variant='primary' onClick={(e) => signInHandler(e, email, pswd)}>SignIn</Button>
</div>
);
}
export default EventPage;
2. State 수신 및 성공 화면 출력 (SuccessPage.jsx)
import { Link, useLocation } from "react-router-dom";
const SuccessPage = () => {
const location = useLocation();
const { user, from } = location.state || {};
const name = localStorage.getItem('userName');
return (
<div>
<center>{name}-{user?.name}님 로그인 성공</center>
<Link to="/read/10">상세페이지로...</Link>
<Link to="/">랜딩페이지로...</Link>
</div>
);
}
export default SuccessPage;
3. QueryString 파싱 및 실패 화면 처리 (ErrorPage.jsx)
import { Link, useSearchParams } from "react-router-dom";
const ErrorPage = () => {
const [searchParams] = useSearchParams();
const category = searchParams.get('category');
const sort = searchParams.get('sort');
return (
<div>
<center>로그인 실패({category} , {sort})</center>
<Link to="/">랜딩페이지로...</Link>
</div>
);
}
export default ErrorPage;
4. Path Variable 파싱 (ViewPage.jsx)
import { useParams } from "react-router-dom";
const ViewPage = () => {
const { id } = useParams();
console.log(`debug >>>> ViewPage useParams : id , ${id}`);
return (
<div>
<h2>상세 보기 페이지 (ID: {id})</h2>
</div>
);
}
export default ViewPage;
🛠️ 실습 / 결과물 & 참고 자료
③ 실습 / 결과물
- 강의 실습코드:
EventPage.jsx, SuccessPage.jsx, ErrorPage.jsx, ViewPage.jsx 코드를 연동하여, 로그인 성공/실패 여부에 따라 state, useSearchParams, useParams 방식으로 데이터를 다르게 전달하고 화면에 동적으로 출력하는 라우팅 시스템 구현.
④ 참고 자료
🔍 문제와 해결
- 막힌 부분:
SuccessPage로 이동 시 직접 URL을 입력해 접근하는 경우 location.state 값이 undefined가 되어 렌더링 에러가 발생하는 문제 점검.
- 해결 방법:
const { user, from } = location.state || {}; 및 옵셔널 체이닝(user?.name) 문법을 활용하여 예외 안전성을 확보하고, localStorage에 저장된 데이터를 백업 수단으로 활용함.
🎯 다음에 할 일