[React] 쿼리(query) 매개변수(라우팅 보완)

SuamKang·2023년 8월 17일
0

React

목록 보기
31/34
post-thumbnail
post-custom-banner

표준 웹 개념인 쿼리 매개변수를 통한 라우팅 개념 보완해보려고 한다.

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


📍 useSearchParams Hook


현재 설정된 쿼리 매개변수에 접근할 수있도록 react-router-dom에서는 useSearchParams훅을 제공한다.
-> 쿼리 매개변수를 공식적으로는 검색매개변수라고 부른다.

이 훅은 배열을 리턴해주고 해당 배열 요소에 구조분해 할당하여 접근 가능하다.

  1. 첫번째는 현재 설정된 쿼리 매개변수에 접근권을 주는 객체가 들어가고
  2. 두번째는 현재 설정된 쿼리 매개변수를 업데이트하는 함수가 들어간다.(위 예제는 링크를 활용해 업데이트 하기에 생략한다.)

그리고 해당 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>
...
  )
}
profile
마라토너같은 개발자가 되어보자
post-custom-banner

0개의 댓글