[React] 링크 연결하기 -Router, Link, useNavigate hook

진히·2023년 8월 3일
3

공부중🤓

목록 보기
3/17
post-custom-banner

우선 라우팅(Routing)이란 무엇일까요?

Routing

경로를 찾는 행위.
웹 프론트엔드에서 라우팅은 url 주소에 따라 다른 화면을 보여주는 것을 의미합니다.

html에서 a 태그를 통해 링크를 걸고 이동했다면 리액트는 다른 방식으로 라우팅을 구현해야 합니다.
리액트 자체에 라우팅 기능이 없어 별도의 라이브러리를 설치하여 라우팅을 구현해야 하고, CRA를 통해 만들 웹 애플리케이션은 SPA이기 때문에 기존의 라우팅 방식과는 다르게 라우팅을 구현해야 합니다.

SPA (Single Page Application)

html이 하나인 웹 애플리케이션.
반대로 html이 여러개인 MPA가 있습니다.

MPA는 html 파일이 여러 개라 다른 페이지를 보여주고 싶을 때, 해당 html 파일을 연결해 보여주는 형태로 페이지 이동하는 기능을 구현할 수 있으나 SPA는 html 파일이 하나이기 때문에 경로에 따라서 다른 UI를 보여주는 라우팅 기능이 필요합니다.

React Router

💻 설치 및 사용방법

1) react-router-dom 설치

먼저 라우팅을 위해 가장 많이 사용되는 라이브러리인 react-router-dom을 설치합니다.
react-router-dom은 리액트에서 라우팅 기능을 구현할 수 있도록 해주는 패키지로, 패키지 안에 있는 컴포넌트를 이용하고자 합니다.

터미널에서 설치할 폴더로 이동한 뒤, 아래 명령어를 작성해 주세요.

$npm install react-router-dom

설치가 완료되었다면 package.json에서 설치 여부를 확인할 수 있습니다.

2) Router 컴포넌트

설치가 완료되었다면 라우팅을 구현할 수 있습니다.
CRA를 통해 프로젝트를 만들었다면 첫 화면에서 App 컴포넌트를 볼 수 있는데 아무리 url을 변경해도 같은 화면이 보이게 됩니다.
때문에 Router 컴포넌트를 만들어 주어야 합니다.

  1. Router.js 파일을 src 폴더 안 index.js와 같은 위치에 생성하고 App.js, App.css 파일은 제거해 주세요.

  2. BrowserRouter, Routes, Route 컴포넌트를 import 하고 import한 3개의 컴포넌트를 이용해서 Router 컴포넌트를 구현해 봅시다.

    1) BrowserRouter 컴포넌트로 전체를 감싸주기
    2) BrowserRouter 컴포넌트의 자식 요소로 Routes 컴포넌트 넣기
    3) Routes 컴포넌트의 자식 요소로 Route 컴포넌트 넣기

    • BrowserRouter 컴포넌트 : 주소 변경에 대해 다양한 편의 기능을 제공해줍니다. (ex. 페이지가 새로고침 되지 않아도 주소 변경이 가능한 기능)
    • Routes 컴포넌트 : 여러 Route를 감싸 그 중 규칙이 일치하는 라우트 단 하나만을 렌더링 시켜줍니다.
    • Route 컴포넌트 : 규칙을 설정할 수 있습니다. path에 경로를 설정하고 element는 path 속성에서 설정한 경로로 이동할 때, 어떤 컴포넌트를 보여줄지 결정하는 속성입니다.
// Router.js

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

const Router = () => {
	return (
		<BrowserRouter>                                    // 1
      <Routes>                                             // 2
        <Route path='/' element={<Components />} />        // 3
      </Routes>
    </BrowserRouter>
	);
};

export default Router;

만약 nav, footer처럼 경로와 상관없이 모든 화면에 표시되어야 하는 컴포넌트가 있다면 Routes 밖에 위치시켜 주세요.

3) 라우팅 구현하기

react-router-dom으로부터 Link 컴포넌트를 import해서 JSX 내부 원하는 곳에 사용할 수 있습니다.

// Login.js

import React from 'react';
import { Link } from 'react-router-dom';

const Login = () => {
  return <Link to='/signup'>회원가입</Link>;
};

export default Login;

회원가입을 클릭하면 /signup이라는 경로로 이동하게 되고, Route 컴포넌트의 path 값 중 일치하는 경로를 찾아 해당 컴포넌트를 화면에 그려줍니다.


🤷‍♀️ 왜 a 태그를 안 쓰고 link를 쓰는걸까?

Link 컴포넌트를 사용하고 실제 페이지를 확인해보면 a 태그로 변환되어있는 것을 확인할 수 있습니다.
그럼 왜 굳이 Link 컴포넌트를 사용하는걸까요?

a 태그는 페이지 이동 시 매번 새로운 페이지를 요청해서 받아와 약간의 변동사항이 있더라도 전체 화면을 매번 다시 렌더링하여 비효율적입니다.

반면, Link 컴포넌트는 실제 서버에 요청을 보내지 않고 url만 변경됩니다.
그래서 실제 화면에서 바뀌어야 하는 부분만 새로 렌더링 되기 때문에 효율적입니다.

🤷‍♀️ 그럼 a 태그는 사용하면 안되나요?

아뇨, 그렇지 않습니다.
애플리케이션 내부에서 페이지를 전환해야 할 때는 Link 컴포넌트를 사용하고,
외부 사이트로 이동할 때는 a 태그를 사용합니다.
외부 사이트로 이동시에는 항상 전체 페이지를 받아와야 하기 때문입니다.


2. useNavvigate hook 사용

  // Login.js

import React from 'react';
import { useNavigate } from 'react-router-dom';               // 1

const Login = () => {
  const navigate = useNavigate();                             // 2

  const goToMain = () => {                                    // 3
    navigate('/main');
  };

  return (
    <button className='loginBtn' onClick={goToMain}>          // 4
      로그인
    </button>
  );
}

export default Login;
  1. useNavigate를 import 합니다.
  2. useNavigate 함수를 실행하고, 반환한 결과를 navigate라는 변수에 할당합니다.
  3. navigate 함수를 호출, 인자에 이동할 경로를 넣어줍니다.
    위의 경우 클릭 시 goToMain이라는 함수를 호출하고 함수 내부에서 navigate('/main')을 호출하면서 Main 페이지로 이동합니다.
  4. button 태그에 onClick 이벤트를 생성, 이벤트 발생 시 실행될 함수를 적어줍니다.


복잡한 useNavigate hook은 왜 사용할까요?
Link 컴포넌트는 to 속성으로 무조건 해당 url로 이동하게끔 되어있습니다.
반면 useNavigate hook은 함수의 호출 형태로 경로 이동을 하기 때문에 특정 조건에서 경로를 이동하게 할 수 있습니다.

 // 실제 활용 예시

const goToMain = () => {
	  if(response.message === 'valid user'){           
    navigate('/main');
  } else {   
    alert('가입된 회원이 아닙니다. 회원가입을 먼저 해주세요.') 
    navigate('/signup');
  }
}

Link 컴포넌트

  • 조건없이 페이지 이동
  • Menu처럼 바로 페이지를 이동하는 경우

useNavigate hook

  • 조건에 따라 페이지 전환
  • 버튼 클릭 시 백엔드 API로 데이터 전송하는 작업을 한 뒤 페이지 이동 또는 userData의 인증 혹은 인가가 필요한 경우 등
profile
티모누나예요🐶
post-custom-banner

1개의 댓글

comment-user-thumbnail
2024년 9월 3일

리액트 정복 중인데 도움 주셔서 감사합니다
본문중에 App.js, App.css 파일은 제거해 주세요. > 하셨는데
제거해야하는 이유가 궁금합니다 ( 저는 App.js 가 없다고 오류가 납니다.. )

답글 달기