본문 바로가기

Framework, Library/React

React_Router 추가

- 쿼리스트링

 

useLocation(Hook)

: location 객체를 반환하며, 이 객체는 현재 보고있는 페이지의 정보를 지니고 있다.

  • pathname: 현재 주소의 경로 (쿼리스트링 제외)
  • search: 맨 앞의 ? 문자 포함한 쿼리스트링 값
  • hash: 주소의 # 문자열 뒤의 값 (주로 History API 가 지원되지 않는 구형 브라우저에서 클라이언트 라우팅을 사용할 때 쓰는 해시 라우터에서 사용합니다.)
  • state: 페이지로 이동할때 임의로 넣을 수 있는 상태 값
  • key: location 객체의 고유 값, 초기에는 default 이며 페이지가 변경될때마다 고유의 값이 생성됨
import {useLocation } from "react-router-dom";
// ... 생략

function About() {
  const location = useLocation();

  return (
    <div>
      <h1>소개</h1>
      <p>About Component</p>
      <p>쿼리스트링: {location.search}</p>
    </div>
  );
}

function App() {
  return (
    <div>
      <h1>React Router Dom example</h1>
      <ul>
		// ...
        <li>
          <Link to="/about">about</Link>
        </li>
      </ul>
      <Routes>
		// ...
        <Route path="/about" element={<About></About>}></Route>
      </Routes>
    </div>
  );
}
// ...

- 중첩된 라우터

 

function Articles() {
  return (
    <ul>
      <li>
        <Link to="/articles/1">게시글 1</Link>
      </li>
      <li>
        <Link to="/articles/2">게시글 2</Link>
      </li>
      <li>
        <Link to="/articles/3">게시글 3</Link>
      </li>
    </ul>
  );
}

function Article() {
  const { id } = useParams();
  return (
    <div>
      <h2>게시글 {id}</h2>
    </div>
  );
}

function App() {
  return (
    // ...
      <li>
        <Link to="/articles">게시글 목록</Link>
      </li>
      <Routes>
        <Route exact path="/" element={<Home></Home>}></Route>
        <Route path="/topics" element={<Topics></Topics>}></Route>
        <Route path="/contact" element={<Contact></Contact>}></Route>
        <Route path="/about" element={<About></About>}></Route>
        <Route path="profiles/:username" element={<Profile></Profile>}></Route>
        <Route path="/articles" element={<Articles></Articles>}></Route>
        <Route path="/articles/:id" element={<Article></Article>}></Route>
      </Routes>
    </div>
  );
}

Articles, Article Component 생성했다.

이때, 게시글을 열었을 대, 게시글 하단에 목록을 보여주고 싶다면?

-> 원래 ArticleList라는 컴포넌트를 따로 만들어서 Component에 삽입해야한다.

 

이번에는 중첩된 라우터(Nested Router)와 Outlet을 사용해보자.

import { Outlet } from 'react-router-dom';

function Articles() {
  return (
    <div>
      <Outlet />
      <ul>
        <li>
          <Link to="/articles/1">게시글 1</Link>
        </li>
        <li>
          <Link to="/articles/2">게시글 2</Link>
        </li>
        <li>
          <Link to="/articles/3">게시글 3</Link>
        </li>
      </ul>
    </div>
  );
};

function App() {
  return (
    <div>
      <h1>React Router Dom example</h1>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/topics">Topics</Link>
        </li>
        <li>
          <Link to="/contact">Contact</Link>
        </li>
        <li>
          <Link to="/about">about</Link>
        </li>
      </ul>

      <p>
        <Link to="/profiles/cml">이창민 프로필</Link>
      </p>
      <p>
        <Link to="/profiles/ccc">없는 프로필</Link>
      </p>
      <li>
        <Link to="/articles">게시글 목록</Link>
      </li>
      <Routes>
        <Route exact path="/" element={<Home></Home>}></Route>
        <Route path="/topics" element={<Topics></Topics>}></Route>
        <Route path="/contact" element={<Contact></Contact>}></Route>
        <Route path="/about" element={<About></About>}></Route>
        <Route path="profiles/:username" element={<Profile></Profile>}></Route>
        <Route path="/articles" element={<Articles></Articles>}>
          <Route path=":id" element={<Article></Article>}></Route>
        </Route>
      </Routes>
    </div>
  );
}


- useNavigate

: Link Component를 사용하지 않고 다른 페이지로 이동을 해야 하는 상황에 사용하는 Hook

 

import { Outlet, useNavigate } from 'react-router-dom';

const Layout = () => {
  const navigate = useNavigate();

  const goBack = () => {
    // 이전 페이지로 이동
    navigate(-1);
  };

  const goArticles = () => {
    // articles 경로로 이동
    navigate('/articles');
  };

  return (
    <div>
      <header style={{ background: 'lightgray', padding: 16, fontSize: 24 }}>
        <button onClick={goBack}>뒤로가기</button>
        <button onClick={goArticles}>게시글 목록</button>
      </header>
      <main>
        <Outlet />
      </main>
    </div>
  );
};

export default Layout;

navigate(-1) : 뒤로 가기

navigate('path') : path로 가기

 

replace 옵션을 추가하면, 페이지를 이동할 때 현재 페이지 기록을 남기지 않는다.

const goArticles = () => {
  navigate('/articles', { replace: true });
}

- NavLink

 

NavLink Component

: 링크에서 사용하는 경로가 현재 라우트의 경로와 일치하는 경우 특정 스타일 또는 CSS 클래스를 적용하는 컴포넌트

 

<NavLink 
  style={({isActive}) => isActive ? activeStyle : undefined} 
/>
<NavLink 
  className={({isActive}) => isActive ? 'active' : undefined} 
/>

실제 사용은 다음과 같다.

import {
  NavLink,
} from "react-router-dom";

function Articles() {
  const activeStyle = {
    color: "red",
    fontSize: 21,
  };

  return (
    <div>
      <Outlet></Outlet>
      <ul>
        <li>
          <NavLink to="/articles/1" style={({ isActive }) => (isActive ? activeStyle : undefined)}>
            게시글 1
          </NavLink>
        </li>
        <li>
          <NavLink to="/articles/2" style={({ isActive }) => (isActive ? activeStyle : undefined)}>
            게시글 2
          </NavLink>
        </li>
        <li>
          <NavLink to="/articles/3" style={({ isActive }) => (isActive ? activeStyle : undefined)}>
            게시글 3
          </NavLink>
        </li>
      </ul>
    </div>
  );
}

Link와 같이, 클릭시 렌더링해주지만, 선택되거나 혹은 조건에 맞는 것만 CSS를 적용시켜주는 역할

만약 같은 컴포넌트를 여러번 출력한다면, 다른 컴포넌트 생성후, 리팩토링 하는 습관을 기르자!

function Articles() {
  return (
    <div>
      <Outlet></Outlet>
      <ul>
        <ArticleItem id={1}></ArticleItem>
        <ArticleItem id={2}></ArticleItem>
        <ArticleItem id={3}></ArticleItem>
      </ul>
    </div>
  );
}
function ArticleItem({ id }) {
  const activeStyle = {
    color: "red",
    fontSize: 21,
  };

  return (
    <li>
      <NavLink
        to={`/articles/${id}`}
        style={({ isActive }) => (isActive ? activeStyle : undefined)}
      >
        게시글 {id}
      </NavLink>
    </li>
  );
}

- NotFound Page

 

path로 '*'를 지정하자. *는 wildcard 문자인데, 아무 텍스트나 매칭한다는 뜻이다.

route element의 상단에 위치하는 route 모두 확인하고 없으면 이 화면이 UI로 출력된다.

<Route path="*" element={<NotFound></NotFound>}></Route>

NotFound Component를 생성하고, Route추가 해주면 끝!


- Navigate Component

: 컴포넌트를 화면에 보여주는 순간 다른 페이지로 이동 하고 싶을 때 사용하는 컴포넌트

페이지를 리다이렉트 하고 싶을때 사용

ex) 사용자의 로그인이 필요한 경우

const Login = () => {
  return <div>로그인 페이지</div>;
};

export default Login;
import { Navigate } from 'react-router-dom';

const MyPage = () => {
  const isLoggedIn = false;

  if (!isLoggedIn) {
    return <Navigate to="/login" replace={true} />;
  }

  return <div>마이 페이지</div>;
};

export default MyPage;
import { Route, Routes } from 'react-router-dom';
import Layout from './Layout';
import About from './pages/About';
import Article from './pages/Article';
import Articles from './pages/Articles';
import Home from './pages/Home';
import Login from './pages/Login';
import MyPage from './pages/MyPage';
import NotFound from './pages/NotFound';
import Profile from './pages/Profile';

const App = () => {
  return (
    <Routes>
      <Route path="/" element={<Layout />}>
        <Route index element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/profiles/:username" element={<Profile />} />
      </Route>
      <Route path="/articles" element={<Articles />}>
        <Route path=":id" element={<Article />} />
      </Route>
      <Route path="/login" element={<Login />} />
      <Route path="/mypage" element={<MyPage />} />
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
};

export default App;

mypage로 이동하면, Login 페이지로 이동된다.

'Framework, Library > React' 카테고리의 다른 글

React_Life Cycle  (0) 2023.01.24
React_JSX  (0) 2023.01.22
React_Router 기본  (0) 2023.01.18
React_DELETE  (0) 2023.01.15
React_UPDATE  (0) 2023.01.15