React Router

우병희·2024년 7월 10일
0

리액트

목록 보기
5/6
post-thumbnail

React router

  • 라우팅은 기본적으로 네트워크에서 경로를 선택하는 프로세스
  • 리액트에서 주소에 따른 컴포넌트 렌더링을 관리하기 위한 라이브러리
  • Routes와 Route는 React Router V6부터 도입된 것

Router

BrowserRouter

  1. BrowserRouter
  • history API를 활용해 history 객체를 생성
  • history API는 내부적으로 stack 자료구조의 형태이므로 사용자가 방문한 url 기록들을 쌓는 형태로 저장
  • 라우팅을 진행할 컴포넌트 상위에 BrowserRouter 컴포넌트 생성 후 감싸주기(여기서는 Router로)
  1. Routes
  • 모든 route의 상위 경로에 존재하며, location 변경 시 하위에 있는 모든 Route 조회 후 현재 location에 맞는 Route를 찾아줌
  1. Route
  • 현재 브라우저의 location 상태에 따른 element 렌더링
  • <Route path="/주소" element={<컴포넌트 />} />

기본 형태

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

function Routing() {
  return (
    <Router>
      <Homenavbar/>
      <Routes>
      <Route path="/" element={<Layout />}>
          <Route index element={<Home/>}/>
          <Route path="search/:query" element={<Search />} />
          <Route path="freeboard" element={<Freeboard />} />
          <Route path="freeboardadd" element={<FreeboardADD />} />
          <Route path="freeboard/:id" element={<FreeboardDetail />} />
          <Route path="freeboardedit/:id" element={<Freeboardedit />} />
          <Route path="secreteboard" element={<Secreteboard />} />
          <Route path="secreteboard/:id" element={<Secreteboarddetail />} />
          <Route path="graduateboard" element={<Graduateboard />} />
          <Route path="graduateboard/:id" element={<Graduateboarddetail />} />
          <Route path="schedule" element={<Schedule />} />
        </Route>
      </Routes>

      <Routes>
      <Route path="/schedule" element={<Schedule/>} />
      </Routes>
    </Router>
  );
}

React-Router-Dom

npm install react-router-dom@latest

Link

  • Link 컴포넌트는 직접적으로 페이지 이동을 하고자 할 때 사용되는 컴포넌트
  • style components로서 감싸질 수도 있어 원하는 형태로 제작도 가능
export const Eachboardword = styled(Link)`
 text-decoration: none;
  font-size: 16px;
  font-weight: bold;
  color: red;
  padding: 10px;
`;
  <Eachboardword to={`/${board.link}`}>
                      {board.title}
                    </Eachboardword>

useParams,useLocation

  • 리액트 라우터 사용시 파라미터 정보를 가져와서 활용하고 싶을 때 useParams를 사용
 <Route path= '/mento' element={<Mento/>}/>
          <Route path='/mento/:id' element={<Mentoprofile/>}/>
            
            
 <Boarddiv to ={`mento/${item.id}`}

                        state={{
                            selectedKeyword: selectedKeyword
                         } }
                    
                 >
import { useParams, useLocation } from "react-router-dom";
 const { id } = useParams();
  const location = useLocation();
 const { selectedKeyword } = location.state || {};
  • 멘토라는 페이지에서 상세 페이지를 /:id로 지정 하여서 useParams를 통해 id 파라미터를 전달 -> 받은 id 값 기반으로 멘토 페이지의 상세 페이지를 id 별로 지정
  • state를 통한 멘토 페이지에서 상세 페이지로의 정보 전달 또한 가능, selectedKeyword 정보를 selectedKeyword라는 이름으로 값 전달 하여 useLocation으로 받은 형태

useNavigte

  • Link 와 마찬가지고 페이지를 이동할 때 사용되며 단순하게 이동 시에는 Link를 쓰는게 좋지만 특정 이벤트 실행 시에 동작하도록 하거나 추가적인 로직이 필요한 경우 useNavigate 사용
import { Link, useNavigate } from "react-router-dom";
  const navigate = useNavigate();
  
   const handleSearchSubmit = (e) => {
    e.preventDefault();
    if (searchQuery.trim()) {
      navigate(`/search/${searchQuery}`);
    }
  };


//router.js
 <Route path="search/:query" element={<Search />} />
  • 위에 코드에서 보이는 것 처럼 함수 실행이라는 이벤트 동작 시에 navigate를 통해 특정 링크로 이동도 하며 주소 이동시에 파라미터를 전달 또한 가능(여기서는 검색 시에 검색 값을 search라는 페이지로 보내어서 검색 값을 포함하는 결과 값을 화면에 출력하도록 하였음)

Outlet

  • 특정 페이지들에 고정적인 레이아웃을 부가하고 싶을 때 주로 사용할 수 있는 구조

  • 상위 component를 고정하고 싶은 레이아웃으로 해둔 뒤에 하위 컴포넌트들을 부가.

  • 여기서는 Layout이라는 컴포넌트를 고정하고 싶은 레이아웃으로 지정하였음

      <Route path="/" element={<Layout />}>
          <Route index element={<Home/>}/>
          <Route path="search/:query" element={<Search />} />
          <Route path="freeboard" element={<Freeboard />} />
          <Route path="freeboardadd" element={<FreeboardADD />} />
          <Route path="freeboard/:id" element={<FreeboardDetail />} />
          <Route path="freeboardedit/:id" element={<Freeboardedit />} />
          <Route path="secreteboard" element={<Secreteboard />} />
          <Route path="secreteboard/:id" element={<Secreteboarddetail />} />
          <Route path="graduateboard" element={<Graduateboard />} />
          <Route path="graduateboard/:id" element={<Graduateboarddetail />} />
          <Route path="schedule" element={<Schedule />} />
        </Route>
      </Routes>
  • 이제 Outlet은 위에서 Layout route의 하위에 포함 된 route들을 가르킴
  • Outlet은 중첩 라우팅을 통한 상위 컴포넌트를 레이아웃 화 하는 것
//Layout.js

import React from "react";
import { Outlet } from "react-router-dom";
import styled from "styled-components";
import { Dropdownmenu } from "../components/Home/Homenavbar";
import Rightbar from "./Rightbar";
// Outlet에 router로 하위에 있는 페이지들을 넣는 것 -> routing 체크

const Layout = () => {
  return (
    <>
      <Dropdownmenu />
      <LayoutContainer>
        <ContentContainer>
          <Outlet />
        </ContentContainer>
        <RightbarContainer>
          <Rightbar />
        </RightbarContainer>
      </LayoutContainer>
    </>
  );
};

const LayoutContainer = styled.div`
  display: flex;
  //argin-top: 200px; // Dropdownmenu 높이만큼 패딩 추가
`;

const ContentContainer = styled.div`
  flex: 1;
  margin-right: 20px; // Rightbar와의 간격 추가
`;

const RightbarContainer = styled.div`
  width: 300px; // Rightbar의 고정 너비 설정
`;

export default Layout;
//Dropdownmenu 컴포넌트

const Dropdownmenu=()=>{

  return(        <DropdownMenu>
    <MenuColumn>
      <MenuItem to={"/freeboard"}>자유게시판 <Symbol></Symbol></MenuItem>
      <MenuItem>비밀게시판 <Symbol></Symbol></MenuItem>
      <MenuItem>졸업생게시판 <Symbol></Symbol></MenuItem>
      <MenuItem>새내기게시판 <Symbol></Symbol></MenuItem>
      <MenuItem>시사·이슈 <Symbol></Symbol></MenuItem>
      <MenuItem>장터게시판 <Symbol></Symbol></MenuItem>
      <MenuItem>정보게시판 <Symbol></Symbol></MenuItem>
      <MenuItem>홍보게시판 <Symbol></Symbol></MenuItem>
    </MenuColumn>
    <Separator />
    <MenuColumn>
      <MenuItem>동아리·학회 <Symbol></Symbol></MenuItem>
      <MenuItem>취업·진로</MenuItem>
    </MenuColumn>
    <Separator />
    <MenuColumn>
      <MenuItem>전산전자공학부 게시판</MenuItem>
      <MenuItem>생명과학부 게시판 <Symbol></Symbol></MenuItem>
      <MenuItem>상사학부 게시판 <Symbol></Symbol></MenuItem>
    </MenuColumn>
    <Separator />
    <MenuColumn>
      <MenuItem>연애/사랑이야기 <Symbol></Symbol></MenuItem>
      <MenuItem>콘디 <Symbol></Symbol></MenuItem>
      <MenuItem>큐피트게시판 <Symbol></Symbol></MenuItem>
      <MenuItem>성 게시판 <Symbol></Symbol></MenuItem>
      <MenuItem>알바생 게시판 <Symbol></Symbol></MenuItem>
      <MenuItem>넷플릭스/왓챠 게시판 <Symbol></Symbol></MenuItem>
      <MenuItem>끝말잇기</MenuItem>
      <MenuItem>썸덕 게시판</MenuItem>
    </MenuColumn>
    <Separator />
    <MenuColumn>
      <MenuItem>요리조리킹 <Symbol></Symbol></MenuItem>
      <MenuItem style={{ color: "#F91F15", fontWeight: "bold" }}>게시판 찾기</MenuItem>
    </MenuColumn>
  </DropdownMenu>)
}


//Rightbar 컴포넌트
const Rightbar = () => { 
  
  return(
 <RightSidebar>
      <form onSubmit={handleSearchSubmit}>
        <SearchBar
          placeholder="전체 게시판의 글을 검색하세요!"
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
        />
      </form>

      <PopularPosts>
        <SectionTitle>실시간 인기 글</SectionTitle>
        {boards.slice(0, 2).map((post, index) => (
          <Sectioneachboard key={index}>
            <Sectionbox height={'75px'} key={post.id} to={`/${post.title}/${post.id}`}>
              {post.title}
            </Sectionbox>
          </Sectioneachboard>
        ))}
      </PopularPosts>

      <SidebarSection>
        <SectionTitle>HOT 게시물</SectionTitle>
        {boards.slice(0, 2).map((post, index) => (
          <Sectioneachboard key={index}>
            <Sectionbox key={post.id} to={`/${post.title}/${post.id}`}>
              {post.title}
            </Sectionbox>
          </Sectioneachboard>
        ))}
      </SidebarSection>
      <SidebarSection>
        <SectionTitle>BEST 게시판</SectionTitle>
      </SidebarSection>
      <SidebarSection>
        <SectionTitle>최근 강의평</SectionTitle>
        {reviews.map((review, index) => (
          <CourseReview key={index}>
            <StarRating rating={review.rating} />
            <ReviewTitle>{review.title}</ReviewTitle>
            <ReviewText>{review.text}</ReviewText>
          </CourseReview>
        ))}
      </SidebarSection>
    </RightSidebar>

  );
};

결과 화면


참고: https://rinn-story.tistory.com/30
참고: https://hsly22xk.tistory.com/405
참고: https://systorage.tistory.com/entry/React-React-Router-v6%EC%97%90%EC%84%9C-query-parameter-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B2%95
참고: https://white120.tistory.com/94
참고: https://velog.io/@kandy1002/React-Router-Dom-%EA%B0%9C%EB%85%90%EC%9E%A1%EA%B8%B0

profile
다른 사람들과 소통하는 개발자가 되고 싶습니다.

0개의 댓글

관련 채용 정보