[포스코x코딩온] 웹개발자 풀스택 부트캠프8기
[포스코x코딩온] React - 웹 렌더링, React Router
항상 발전하는 개발자
2023. 9. 27. 17:49
728x90
React - 웹 렌더링
SPA
- Single Page Application
- 단일 웹페이지로 돌아가는 애플리케이션(index.html)
- 브라우저에서 자바스크립트를 이용해 단일 웹페이지 상의 HTML 요소를 동적으로 생성 및 동작
- 검색 엔지 최적화(SEO)에 적합하지 않다.
- React, Svelte, Vue.js와 같은 라이브러리로 개발 가능
※MPA(Multi Page Application): 여러 페이지를 만들고, 각 요청에 따라 적절한 페이지를 보여주는 방식
React Router
라우팅(Routing)이란?
- 사용자가 요청한 URL에 따라 해당 URL에 맞는 페이지를 보여주는 것
- 가장 많이 사용하는 라이브러리는 "React Router"이다.
https://reactrouter.com/en/main
Home v6.16.0
I'm on v5 The migration guide will help you migrate incrementally and keep shipping along the way. Or, do it all in one yolo commit! Either way, we've got you covered to start using the new features right away.
reactrouter.com
React Router
- 개발자가 주소별로 다른 컴포넌트를 보여주기 위해 사용하는 라이브러리
- 여러 환경에서 동작할 수 있도록 여러 종류의 라우터 컴포넌트 제공
- 주요 컴포넌트
- BrowserRouter
- Routes
- Route
- Link
- createBrowserRouter
npm i react-router-dom@6 #버전6 지정 설치
BrowserRouter
- <BrowserRouter>
- HTML5를 지원하는 브라우저의 주소 감지
- Router의 역할
- 새로고침을 하지 않아도 새로운 컴포넌트를 렌더링 해주는 기능 담당
- URL마다 컴포넌트가 바뀔 때 이때 바뀌는 부분의 최상단에 위치해야 한다.
import { BrowserRouter } from 'react-router-dom';
// ... //
const ReactRouter = () =>{
return (
<div>
<BrowserRouter>
</BrowserRouter>
</div>
);
}
Routes, Route
- <Routes>, <Route>
- 경로가 일치하는 컴포넌트를 렌더링 해주도록 경로 매칭
- Route에서는 구체적으로 어떤 컴포넌트를 렌더링 할지 결정
- path: 경로
- element: 연결한 컴포넌트
- 즉, /about라는 url 주소로 가면 About 컴포넌트를 불러온다.
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/user" element={<User />} />
<Route path="/user/:userId" element={<UserDetail />} />
<Route path="/redirect" element={<Redirect />} />
<Route path="*" element={<NotFound />} />
</Routes>
- BrowserRouter와 Routes, Route를 이용하여 사용할 수 있다.
export default function Router() {
return (
<>
<BrowserRouter>
<Header />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/user" element={<User />} />
<Route path="/user/:userId" element={<UserDetail />} />
<Route path="/redirect" element={<Redirect />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
</>
);
}
Link
- <Link>
- 경로를 변경한다.
- 기존 HTML의 a태그가 새로고침을 해 렌더링을 수행한다면 <Link> 컴포넌트는 페이지 전환을 방지한다.
- 아래와 같이 Link를 사용하여 a태그처럼 페이지를 이동할 수 있지만, 페이지가 새로고침을 하지는 않는다.
import { Link, redirect, useNavigate } from "react-router-dom";
//a 태그는 페이지가 새로고침이 되지만
//Link는 컴포넌트만 변하기 떄문에 새로고침이 되지 않는다.
export default function Header() {
//useNavigate():Link컴포넌트를 사용하지 않고 사용자를 어딘다로 이동시키는 기능(간접적으로 이동)
// -1 :이전 페이지로 이동
// 루트페이지를 통해 이동하려면 '/'를 적고 기존 URL에 계속 뒤에 붙여서 사용하려면 '/'를 사용하지 않는다.
const navi = useNavigate();
const onClick = () => {
navi("redirect");
};
//Link: 유저가 클릭
return (
<div>
<ul>
<li>
<a href="/about">About</a>
</li>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/user">User</Link>
</li>
<li>
<button onClick={onClick}>Redirect</button>
</li>
</ul>
</div>
);
}
createBrowserRouter
- 현재 React Router에서 밀고 있는(?) 방식.
- <BrowserRouter> , <Routes> , <Route>을 사용하지 않는다.
- 위의 코드와 동일한 결과를 도출한다.
- children 안에 있는 경우 부모 경로 뒤에 경로가 붙게 된다.
const Router = createBrowserRouter([
{
path: "/",
element: <App />,
children: [
{
path: "",
element: <Home />,
errorElement: <Error />,
},
{
path: "about",
element: <About />,
},
{
path: "redirect",
element: <Redirect />,
},
],
errorElement: <NotFound />, //에러 처리
},
{
path: "/user",
element: <App />,
children: [
{ path: "", element: <User /> },
{
path: ":userId",
element: <UserDetail />,
children: [
{
path: "Comment",
element: <comment />,
},
],
},
],
},
]);
Outlet
- 중첩 라우트 렌더링: Outlet은 중첩 라우트의 부모 라우트 컴포넌트 내에서 사용되어, 해당 부모 라우트의 URL과 일치하는 자식 라우트 컴포넌트를 렌더링
- context를 이용하여 자식 라우트에 데이터 전송 가능. 자식 라우트에서는 useOutletContext() 사용
function App(){
return(
<>
<Header />
<Outlet /> 자식 컴포넌트들도 불러오는 것
</>
);
}
- URL 파라미터
- useParams()
- /product/:id
- 경로에 : 를 사용해 설정되는 것
- URL 파라미터가 여러 개인 경우 /product/:id/:name 처럼 설정
- URL 퀴리스티링
- useSearchParams()
- 페이지 이동
- useNavigate()
- Link 컴포넌트를 사용하지 않고 다른 페이지로 이동해야 하는 경우, 뒤로가기 등에 사용한다.
const navigate = useNavigate();
<li><button onClick={() => navigate(-2)}> 2페이지 뒤로</button></li>
<li><button onClick={() => navigate(-1)}> 1페이지 뒤로</button></li>
<li><button onClick={() => navigate(1)}> 1페이지 앞으로</button></li>
<li><button onClick={() => navigate(2)}> 2페이지 앞으로</button></li>
<li><button onClick={() => navigate('/')}> Root 페이지로</button></li>
아래 코드를 콘솔을 확인하면서 보면 이해할 수 있다.
import { Link, useSearchParams } from "react-router-dom";
export const users = [
{ id: 1, name: "홍길동", comment: [{ text: "안녕하세요" }] },
{ id: 2, name: "이몽룡", comment: [{ text: "반갑습니다" }] },
{ id: 3, name: "암꺽정", comment: [{ text: "어서오세요" }] },
];
export default function User() {
//searchParams는 쿼리스트링 값을 가져오는 것
//setSearchParams는 쿼리스트링 값을 할당하는 것
const [searchParams, setSearchParams] = useSearchParams();
console.log(searchParams.get("mode"));
//user?name=hello&mode=Dark 로 사용해야 한다. ? 뒤에 붙여야 한다.
setTimeout(() => {
setSearchParams({ mode: "Light" });
}, 3000);
//3초후에 mode 값을 Light로 변경하게 설정할 수 있다.
return (
<div>
<ul>
{users.map((value) => {
return (
<li key={value.id}>
<Link to={`/user/${value.id}`}>{value.name}</Link>
</li>
);
})}
</ul>
</div>
);
}
실습 영상
코드
- App.js
import Router from "./Router";
function App() {
return (
<>
<Router />
</>
);
}
export default App;
- Router.js
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Main from "./12Router/Main";
import Student from "./12Router/Student";
export default function Router() {
return (
<>
<BrowserRouter>
<Routes>
<Route path="/" element={<Main />} />
<Route path="/student/:name" element={<Student />} />
</Routes>
</BrowserRouter>
</>
);
}
- Main.js
import { Link, Route, Routes } from "react-router-dom";
import Student from "./Student";
export default function Main() {
return (
<>
<Link to="/">
<h2>ReactRouter 실습</h2>
</Link>
<nav>
<ul>
<li style={{ margin: "4px" }}>
<Link to="/student/kdt">학생KDT</Link>
</li>
<li style={{ margin: "4px" }}>
<Link to="/student/codingon">코딩온</Link>
</li>
<li style={{ margin: "4px" }}>
<Link to="/student/new?name=kdt3rd">searchParams</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/student/kdt" element={<Student />} exact />
</Routes>
</>
);
}
- Student.js
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
const nameStyle = {
color: "orange",
};
export default function Student() {
const navi = useNavigate();
const onClick = () => {
navi(-1);
};
const params = useParams();
console.log(params);
const { name } = useParams();
const [searchParams, setSearchParams] = useSearchParams();
console.log(searchParams.get("name"));
const realName = searchParams.get("name");
return (
<>
<h2>
학생이름은 <span style={nameStyle}>{name}</span> 입니다.
</h2>
{realName && <h2>실제 이름은 {searchParams.get("name")}</h2>}
<button onClick={onClick}>이전 페이지로</button>
</>
);
}
이처럼 컴포넌트를 직접 불러와서 웹에 렌더링 할 수 있다. 이제 사용자에서 여러 개의 페이지를 보여줄 수 있게 되었다.!!!!!!
728x90