react-router-dom | Link, usePrams 로 로그인 페이지 구현해보기

imzzuu·2022년 5월 25일
1

이전 포스트에서 SPA 에 대해 다뤄보았다.
react 프로젝트에서 SPA를 쉽게 도입할 수 있도록 도와주는 라이브러리가 있는데,
바로 react-router 이다!

react-router란?


react 프로젝트에서 SPA를 쉽게 도입할 수 있도록 도와주는 라이브러리

설치 : $ npm i react-router or $ npm i react-router-dom

react-router-dom 을 설치하는 이유 ? 브라우저에서 사용할 것이기 때문에

Link와 Routes


import { BrowserRouter, Route, Routes } from "react-router-dom";

const Hello = () => (
 <Link to='/'>to home</Link>
);

const Main = () => (
 <Link to='/hello'>to hello</Link>
);

const App = () => {
 return (
 <BrowserRouter>
 <Routes>
 <Route path="/" element={<Main />} />
 <Route path="/hello" element={<Hello />} />
 </Routes>
 </BrowserRouter>
)
}

<Routes /> : 를 아래와 같이 동작하도록 만듦
<Route /> : props.path와 브라우저의 url이 일치하면 props.element를 return
가장 먼저 일치하는 Route 만 적용
<Link /> : props.to 에 적힌 url로 http get request를 보내지 않고
브라우저에 표시되는 url만 변경

Parameter


path 에 동적인 값을 주기 위해서 가변 parameter의 앞에 콜론(:)를 붙이면
뒤 string 을 key로하는 parameter를 받을 수 있다.

import { BrowserRouter, Route, Routes, Link, useParams } from "react-router-dom";

//  Hello 컴포넌트
const Hello = () => {

// 공식적인 react의 hook 아니고 react-router-dom 서 hook 처럼 만든 것
 const params = useParams();
 console.log(params); // Object { id: '5' }

 return (
 <Link to='/'>to home</Link>
 );
}

//  Main 컴포넌트
const Main = () => (
 <Link to='/hello/5'>to hello with id 5</Link>
);

const App = () => {
 return (
 <BrowserRouter>
 <Routes>
 <Route path="/" element={<Main />} />
 <Route path="/hello/:id" element={<Hello />} />
 </Routes>
 </BrowserRouter>
)
}
  • [:id], /:id? : optional parameter
    v6 로 넘어오면서 없을 경우를 대비하여 optional parameter 를 설정하기보단 없을 때의 component 를 만들어서 랜더를 하도록 하는 것을 권장한다.


  • 2개 이상의 params 를 사용해야할 경우

    아래처럼 path 를 구분하는 것보다

     <Route path="/hello/:id:pw" element={<Hello />} />

    search query 를 이용하는 것이 바람직하다.

     <Route path="/hello" element={<Hello />} />

    로 하고 이런 식으로 url 처리를 하고,

    const Main = () => (
     <Link to='/hello/?id=5&pw1234'>to hello with id 5</Link>
    );
    

    useLocation 의 serch 를 변수에 담아서 활용하는 것이 바람직하다.


    예제


    지난번 실습 때 만든 회원가입 form 컴포넌트에서
    회원가입 성공시 alert를 띄우는 대신
    안녕하세요 {id}님! 이 적힌 페이지로 이동시키기

    🔗 index.js

     // react-router-dom 에서 BrowserRouter, Route, Routes 꺼내오기
     import { BrowserRouter, Route, Routes } from "react-router-dom";
     import Hello from "./Router/Hello";
     import UseRefEx from "./UseRefEx";
     
     const root = ReactDOM.createRoot(document.getElementById("root"));
     root.render(
       <React.StrictMode>
         <BrowserRouter>
           <Routes>
             {/* React elememt 를 보여준다. */}
             <Route path="/" element={<UseRefEx />} />
             <Route path="/:id" element={<Hello />} /> 
     								=> id 값에 따라 동적으로 보여줄 컴포넌트
           </Routes>
         </BrowserRouter>
       </React.StrictMode>
     );

    <Route path="/:id" element={<Hello />} /> => id 값에 따라 동적으로 보여줄 컴포넌트
    : parameter 를 통해 동적으로 path 값을 주어서 컴포넌트를 그리도록 셋팅


    🔗 UseRefEx.js (로그인 폼 컴포넌트)

    이전 코드에서 달라진 부분은

    1. button을 로그인 완료 페이지로 넘겨줄 Link 로 감싸주기
          <Link to={`/${id}`}>
                <button
                  type="button"
                  onClick={handleClick}
                  disabled={id.length < 1 && password.length < 1 && email.length < 1}
                >
                  회원가입
                </button>
              </Link>
      이때 Link 의 종착지는 path="/:id" 의 path 를 갖는 <Hello /> 컴포넌트이다.
      그렇기 때문에 to 에 id ( id input 의 value ) 를 params 로 넣어준다.

    1. 회원가입이 완료되고 로그인창으로 넘어가지 않는 조건들일 때 button 의 submit 동작을 막는다. (id, pw, email 가 유요하지 않을 때)

      
        const handleClick = (e) => {
          if (!vaildId) {
            e.preventDefault();
            alert("유효하지 않은 id 입니다.");
            setInputs({
              ...inputs,
              id: "", // 바뀐 값 빼고 나머지는 그대로 스프레드 연산자
            });
            inutRef.current[0].focus();
          } else if (!vaildPassword) {
            e.preventDefault();
            alert("유효하지 않은 password 입니다.");
            inutRef.current[1].focus();
            setInputs({
              ...inputs,
              password: "",
            });
          } else if (!vaildEmail) {
            e.preventDefault();
            alert("유효하지 않은 email 입니다.");
            inutRef.current[2].focus();
            setInputs({
              ...inputs,
              email: "",
            });
          }
        };

      각각 e.preventDefault() 를 해주었다!

      이렇게 하면, 유효성 검사를 모두 통과했을 경우에만 Link 를 통해 컴포넌트 간 이동을 할 수 있다.

    🔗 Hello.js (로그인/회원가입 완료 컴포넌트)

    import { Link, useParams } from "react-router-dom";
    export default function Hello() {
      const { id } = useParams();
      return (
        <div>
          <p>안녕하세요{id}! </p>
          <Link to="/">
            <button>로그아웃</button>
          </Link>
        </div>
      );
    }

    usePrams 를 통해 받아온 데이터는 우리가 :id 에 작성한 id 라는 키에 값이 담겨져있다.

    그렇기 때문에 비구조화할당을 통해 id 값을 받아오고, 해당 id 를 html 에 그려주면 완성!

    또한, 로그아웃 버튼을 누르면 다시 회원가입 (로그인) 폼으로 돌아간다.

profile
FrontenDREAMER

0개의 댓글