티스토리 뷰
Reference
이 프로젝트는 코딩애플 리액트 강의를 참고하여 제작되었습니다.
https://codingapple.com/course/react-basic/
React 리액트 기초부터 쇼핑몰 프로젝트까지!
Next.js는 프론트엔드부터 서버까지 만들 수 있는 React기반 프레임워크입니다. 이것만 사용해도 풀스택 웹개발이 가능합니다. Next.js 사용시 서버사이드 렌더링이 쉽기 때문에 React, Vue만 사
codingapple.com
맨파워/맵/404 페이지 만듭니다.
회사소개 페이지 같은거 있으면 있어 보일것 같습니다.
굿즈 아래에 기분좋게 콤파니 콤포넌트 하나 빌딩 합니다.
function Company() {
return (
<div>
<h4>company</h4>
It's a company
</div>
);
}
라우츠 내부 라우트디테일 아래에 라우트를 추가 합니다.
<Route path="/company" element={<Company />} />
네브 내부 디테일링크 아래에 링크 추가 합니다.
네브 콤파니 탭해서 성능 체크 합니다.
<Link to="/company" class="nav-link active" aria-current="page">
Company
</Link>
회사소개를 카테고리 메인으로 설계합니다.
그리고 서브페이지로 맨파워/맵 페이지 만들고 싶습니다.
리액트에서 제공하는 아울렛 라이브러리 사용하면 됩니다.
일단 콤파니 라우트 변경하고 내부 코드 추가 합니다.
<Route path="/company" element={<Company />}>
<Route
path="manpower"
element={
<div>
{" "}
<img
src="https://plus.unsplash.com/premium_photo-1688821131205-52f5c633ce69?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
width="80%"
/>
</div>
}
/>
<Route
path="map"
element={
<div>
<img
src="https://images.unsplash.com/photo-1548345680-f5475ea5df84?q=80&w=2073&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
width="80%"
/>
</div>
}
/>
</Route>
아울렛으로 구멍을 뚧어 둡니다.
리액트는 이렇게 하면 알아서 다 해줍니다.
이 아울렛 태그가 핵심입니다.
function Company() {
return (
<div>
<h4>company</h4>
<p>It's a company</p>
<Outlet></Outlet>
</div>
);
}
아울렛으로 업그레이드 하기 위해 네브에 이 코드를 삭제 합니다.
<Link to="/company" class="nav-link active" aria-current="page">
Company
</Link>
삭제한 자리에 맨파워 맵 링크 추가 합니다.
<Link
to="/company/manpower"
class="nav-link active"
aria-current="page"
>
Manpower
</Link>
<Link
to="/company/map"
class="nav-link active"
aria-current="page"
>
Map
</Link>
언제나 금쪽이들은 존재 합니다.
이상한 유알엘 접근 시도하는 금쪽이를 대비해 예외처리 하겠습니다.
금쪽이에게 한심좌를 선물 합니다.
라우츠내부 맨 아래에 위 코드를 추가합니다.
* 는 라우츠에 존재하는 패스를 제외한 모든 것을 뜻합니다.
<Route
path="*"
element={
<div>
<h4>No page</h4>
<p>hmmm....</p>
<img
src="https://cdn.maily.so/ixmvzk5qh83mee5kcjw8pp55fihe"
width="80%"
/>
</div>
}
/>
TEST 진
네브로 맨파워/맵 체크합니다.
혁명적인 유알엘도 찍어서 예외처리도 체크 해 봅니다.
http://localhost:3000/jinukcute



Completion
import { useState } from 'react';
import reactLogo from './assets/react.svg';
import viteLogo from '/vite.svg';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { Routes, Route, Link, Outlet } from 'react-router-dom';
import data from './data.jsx';
import Detail from './routes/Detail';
export default function App() {
let [shoes] = useState(data);
return (
<div className="App">
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">
Navbar
</a>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNavAltMarkup"
aria-controls="navbarNavAltMarkup"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<Link to="/" class="nav-link active" aria-current="page">
Home
</Link>
<Link to="/detail" class="nav-link active" aria-current="page">
Detail
</Link>
<Link
to="/company/manpower"
class="nav-link active"
aria-current="page"
>
Manpower
</Link>
<Link
to="/company/map"
class="nav-link active"
aria-current="page"
>
Map
</Link>
</div>
</div>
</div>
</nav>
<Routes>
<Route
path="/"
element={
<>
<div className="main-bg"></div>
<h1 className="my-5">Nike shop</h1>
<div className="d-flex flex-column mb-3">
{shoes.map((shoe, i) => {
return <Goods shoes={shoe} i={i}></Goods>;
})}
</div>
</>
}
/>
<Route path="/detail" element={<Detail />} />
<Route path="/company" element={<Company />}>
<Route
path="manpower"
element={
<div>
{' '}
<img
src="https://plus.unsplash.com/premium_photo-1688821131205-52f5c633ce69?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
width="80%"
/>
</div>
}
/>
<Route
path="map"
element={
<div>
<img
src="https://images.unsplash.com/photo-1548345680-f5475ea5df84?q=80&w=2073&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
width="80%"
/>
</div>
}
/>
</Route>
<Route
path="*"
element={
<div>
<h4>No page</h4>
<p>hmmm....</p>
<img
src="https://cdn.maily.so/ixmvzk5qh83mee5kcjw8pp55fihe"
width="80%"
/>
</div>
}
/>
</Routes>
<div class="card m-5">
<div class="card-header">Featured</div>
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">
With supporting text below as a natural lead-in to additional
content.
</p>
<a href="#" class="btn btn-primary">
Go somewhere
</a>
</div>
</div>
</div>
);
}
function Goods(props) {
return (
<div className="p-2">
<img
src={
'https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/ca-shop/s' +
(props.i + 1) +
'.PNG'
}
width="80%"
/>
<h4 className="my-3">{props.shoes.title}</h4>
<p>{props.shoes.price}</p>
</div>
);
}
function Company() {
return (
<div>
<h4>company</h4>
<p>It's a company</p>
<Outlet></Outlet>
</div>
);
}
라우트 엘레멘트 콤파니 패밀리를 컴포넌트로 분리 합니다.
라우트 코드를 보고 있자니 코드가 어느새 산만해 졌습니다.
울화통이 치밉니다. 개선 합니다.
컴파니 아래 라우트에 있던 엘레멘트를 컴포넌트로 옮깁니다.
function Company() {
return (
<div>
<h4 className="my-3">company</h4>
<p>It's a company</p>
<Outlet></Outlet>
</div>
);
}
function Manpower() {
return (
<div>
<img
src="https://plus.unsplash.com/premium_photo-1688821131205-52f5c633ce69?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
width="80%"
/>
</div>
);
}
function Map() {
return (
<div>
<img
src="https://images.unsplash.com/photo-1548345680-f5475ea5df84?q=80&w=2073&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
width="80%"
/>
</div>
);
}
function Nopage() {
return (
<div>
<h4 className="my-2">No page</h4>
<p>hmmm....</p>
<img
src="https://cdn.maily.so/ixmvzk5qh83mee5kcjw8pp55fihe"
width="80%"
/>
</div>
);
}
라우츠 내부에 라우트디테일 아래에 라우트를 이렇게 정리해 봅니다.
그닥 깨끗해 진것 같지는 않습니다.
리액트 코드는 좀 더티섹시한 것 같습니다.
<Route path="/company" element={<Company />}>
<Route path="manpower" element={<Manpower />} />
<Route path="map" element={<Map />} />
</Route>
<Route path="*" element={<Nopage />} />
test
뷰가 같다면 그뤠잇!
Completion
import { useState } from 'react';
import reactLogo from './assets/react.svg';
import viteLogo from '/vite.svg';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { Routes, Route, Link, Outlet } from 'react-router-dom';
import data from './data.jsx';
import Detail from './routes/Detail';
export default function App() {
let [shoes] = useState(data);
return (
<div className="App">
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">
Navbar
</a>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNavAltMarkup"
aria-controls="navbarNavAltMarkup"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<Link to="/" class="nav-link active" aria-current="page">
Home
</Link>
<Link to="/detail" class="nav-link active" aria-current="page">
Detail
</Link>
<Link
to="/company/manpower"
class="nav-link active"
aria-current="page"
>
Manpower
</Link>
<Link
to="/company/map"
class="nav-link active"
aria-current="page"
>
Map
</Link>
</div>
</div>
</div>
</nav>
<Routes>
<Route
path="/"
element={
<>
<div className="main-bg"></div>
<h1 className="my-5">Nike shop</h1>
<div className="d-flex flex-column mb-3">
{shoes.map((shoe, i) => {
return <Goods shoes={shoe} i={i}></Goods>;
})}
</div>
</>
}
/>
<Route path="/detail" element={<Detail />} />
<Route path="/company" element={<Company />}>
<Route path="manpower" element={<Manpower />} />
<Route path="map" element={<Map />} />
</Route>
<Route path="*" element={<Nopage />} />
</Routes>
<div class="card m-5">
<div class="card-header">Featured</div>
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">
With supporting text below as a natural lead-in to additional
content.
</p>
<a href="#" class="btn btn-primary">
Go somewhere
</a>
</div>
</div>
</div>
);
}
function Goods(props) {
return (
<div className="p-2">
<img
src={
'https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/ca-shop/s' +
(props.i + 1) +
'.PNG'
}
width="80%"
/>
<h4 className="my-3">{props.shoes.title}</h4>
<p>{props.shoes.price}</p>
</div>
);
}
function Company() {
return (
<div>
<h4 className="my-3">company</h4>
<p>It's a company</p>
<Outlet></Outlet>
</div>
);
}
function Manpower() {
return (
<div>
<img
src="https://plus.unsplash.com/premium_photo-1688821131205-52f5c633ce69?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
width="80%"
/>
</div>
);
}
function Map() {
return (
<div>
<img
src="https://images.unsplash.com/photo-1548345680-f5475ea5df84?q=80&w=2073&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
width="80%"
/>
</div>
);
}
function Nopage() {
return (
<div>
<h4 className="my-2">No page</h4>
<p>hmmm....</p>
<img
src="https://cdn.maily.so/ixmvzk5qh83mee5kcjw8pp55fihe"
width="80%"
/>
</div>
);
}
참고사이트 : ca04
ca04
Reference이 프로젝트는 코딩애플 리액트 강의를 참고하여 제작되었습니다.https://codingapple.com/course/react-basic/ React 리액트 기초부터 쇼핑몰 프로젝트까지! Next.js는 프론트엔드부터 서버까지 만들 수
lshjju.tistory.com
'프로그래밍언어 > 리엑트' 카테고리의 다른 글
| [React] 프로젝트 만들기 part6 (1) | 2026.03.21 |
|---|---|
| [React] 프로젝트 만들기 part5 (0) | 2026.03.21 |
| [React] 프로젝트 만들기 part3 (0) | 2026.03.21 |
| [React] 프로젝트 만들기 part2 (0) | 2026.03.21 |
| [React] Context API - 리액트 콘텍스트 에이피아이 (0) | 2026.03.21 |
