표준 웹 개념인 쿼리 매개변수를 통한 라우팅 개념 보완해보려고 한다.
import { useState } from "react";
import { Form } from "react-router-dom";
import classes from "./AuthForm.module.css";
function AuthForm() {
const [isLogin, setIsLogin] = useState(true);
const changeAuthHandler = () => {
setIsLogin((prevIsLogin) => !prevIsLogin);
};
return (
<>
<Form method="post" className={classes.form}>
<h1>{isLogin ? "Log in" : "Create a new user"}</h1>
<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}>
<button onClick={changeAuthHandler} type="button">
{isLogin ? "Create new user" : "Login"}
</button>
<button>Save</button>
</div>
</Form>
</>
);
}
export default AuthForm;
현재 로딩하는 양식에 따라 다른 정보를 서버에 보내고 있는 상황이다.
(로그인 상태이면 '회원가입'텍스트 버튼 나오게, 회원가입상태이면 '로그인'텍스트 버튼 나오게)
위 로직에서 로그인 로딩상태에 따라서 양식이 다르고 이 다른 양식으로 서버에 보내는 상황에 쿼리를 사용해보아도 좋다.
url에서 물음표 뒤에 붙는 매개변수인데 이 매개변수를 추가해서 정확히 어떤 컴포넌트가 주어지는지 정의할 수 있다. ex) /auth?mode=signup
: 해당 페이지를 회원가입 혹은 로그인 모드에 직접 연결할 수 있다는 것이다. 그러면 같은 페이지에 다른 UI가 렌더링 된 거라고 해도 사용자를 회원가입 페이지로 직접연결할 수 있다.
쉽게말해 페이지는 같지만 모드별로 양식이 다르게 나오게 되는것이다.
즉, 현재 useState 상태기반 로직을 쿼리 기반 로직으로 대체하려는 것이다.
먼저 기존 상태기반 로직을 지우고 버튼으로 이벤트를 생성하던 부분을 링크컴포넌트로 대체해준다.
import { Form, Link } from "react-router-dom";
import classes from "./AuthForm.module.css";
function AuthForm() {
return (
<>
<Form method="post" className={classes.form}>
<h1>{isLogin ? "Log in" : "Create a new user"}</h1>
<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="">{isLogin ? "Create new user" : "Login"}</Link>
<button>Save</button>
</div>
</Form>
</>
);
}
export default AuthForm;
그리고 해당 경로는 현재 활성상태인 경로임이 확인이 되고있으니 상대경로로 /auth를 생략하고 '?'뒤에 mode라는 이름를 추가해 링크를 클릭하면 나올 값을 정해준다. -> 로그인 모드이면 ?mode=signup
설정 , 회원가입 모드이면 ?mode=login
현재 설정된 쿼리 매개변수에 접근할 수있도록 react-router-dom에서는 useSearchParams훅을 제공한다.
-> 쿼리 매개변수를 공식적으로는 검색매개변수라고 부른다.
이 훅은 배열을 리턴해주고 해당 배열 요소에 구조분해 할당하여 접근 가능하다.
그리고 해당 searchParams객체에 접근할 때 특정 쿼리 매개변수에 대한 값을 가져올 수 있도록 해주는 get메소드를 사용해야한다.
import { Form, Link, useSearchParams } from "react-router-dom";
import classes from "./AuthForm.module.css";
function AuthForm() {
// 첫번째 요소: 접근가능한 객체, 두번째요소: 업데이트 함수(생략)
const [searchParams] = useSearchParams();
// 해당 mode가 login인임을 설정해준다.(기준)
const isLogin = searchParams.get("mode") === "login";
return (
<>
<Form method="post" className={classes.form}>
<h1>{isLogin ? "Log in" : "Create a new user"}</h1>
<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>Save</button>
</div>
</Form>
</>
);
}
export default AuthForm;
이렇게 하면 두개의 모드를 전환할 수 있는 링크가 생긴다.
state를 사용의 대안이긴 하지만 특정모드의 페이지로 직접 연결할 수 있게 되었다.
마지막으로 MainNavigation컴포넌트에 가서 기본 인증 페이지로 로딩되게 설정하고 마무리 하면 되겠다.
function MainNavigation() {
return (
...
<li>
<NavLink
to="/auth?mode=login"
className={({ isActive }) =>
isActive ? classes.active : undefined
}
>
Authentication
</NavLink>
</li>
...
)
}