페이지를 나누고 싶으면 일반 html, css, js 사이트는 하나의 페이지마다 각각 html파일을 만들었지만 리액트에서는 html 파일을 하나만 사용한다.
그래서 리액트에선 다른 페이지를 요청하면 내부에 있는
직접 구현도 가능하나 일반적으로 react-router-dom 이라는 외부 라이브러리를 설치해 구현한다.
npm install react-router-dom@6
// index.js
// ⑴import 하기
import { BrowserRouter } from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
// ⑵ <App/> 컴포넌트를 <BrowserRouter>로 감싸기
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
// (App.js)
import { Routes, Route, Link } from 'react-router-dom'
function App(){
return (
// 생략..
<Routes>
<Route path="/detail" element={ <div>상세페이지임</div> } />
<Route path="/about" element={ <div>어바웃페이지임</div> } />
</Routes>
)
import
한다.<Routes>
를 만들고 그 안에 <Route>
를 작성 한다.<Route path=’url’ element={<보여줄html>} />
example.com/detail 로 접속하면 detail 페이지를 보여주고
example.com/about 로 접속하면 about페이지를 보여준다.
<Route path="/" element={ <div>메인페이지에서 보여줄 내용</div> } />
/
는 메인페이지를 나타내 준다.
사용자들은 주소창에 url을 입력해 들어가지 않고 링크를 눌러 페이지에 들어 간다.
링크를 만들고 싶으면 react-router-dom
에서 Link
컴포넌트를 import
해 오고 원하는 곳에서 <Link>
컴포넌트를 쓰면 된다.
<Link to="/">홈</Link>
<Link to="/detail">상세페이지</Link>
import { useNavigate} from 'react-router-dom';
function App(){
let navigate = useNavigate()
return (
// 생략...
<button onClick={()=>{ navigate('/detail') }}>이동버튼</button>
)
}
useNavigate()
는 페이지를 이동시켜주는 함수를 반환한다.
navigate('/detail')
시, /detail
페이지로 이동이 가능하다.
혹은 인수에 숫자를 쓰면 앞으로가기, 뒤로가기 등이 가능하다.
-1 은 뒤로 1번 가기
2 는 앞으로 2번 가기
사용자가 고의적으로 혹은 의도치 않게 잘못된 방식으로 페이지에 접근하려할 경우 등 ‘없는 페이지입니다’ 같은 내용의 페이지를 보여주려면
<Route path="*" element={ <div>없는페이지임</div> } />
라우트의 맨 밑에 위와 같은 *
경로의 패스를 만들어 둔다.
이는 모든 경로를 뜻해서 위에 만들어둔 라우트들이 아니라면 *
경로로 이동한다.
/about/member
로 접속하면 회사멤버를 소개하는 페이지
/about/location
로 접속하면 회사의 위치를 소개하는 페이지를 만들고 싶다면 단순하게
<Route path="/about/member" element={ <div>멤버들</div> } />
<Route path="/about/location" element={ <div>회사위치</div> } />
라고 할 수도 있지만 <Route>
안에 <Route>
를 넣는
즉, Nested routes를 쓸 수 있다.
<Route path="/about" element={ <About/> } >
<Route path="member" element={ <div>멤버들</div> } />
<Route path="location" element={ <div>회사위치</div> } />
</Route>
Outlet
nested route안의 element
들을 어디에 보여줄지 위치를 지정해 주는 것이 Outlet
이다.
function About(){
return (
<div>
<h4>about페이지임</h4>
<Outlet></Outlet>
</div>
)
}
<Route path="/detail/:id" element={ <Detail shoes={shoes}/> }/>
/:
는 아무 문자를 뜻하며 뒤에오는 값을 url의 파라미터로 전송이 가능하다.
위 라우트는 주소창에 /detail/아무거나
를 입력했을 때 <Detail />
컴포넌트를 보여 달라는 뜻이다.
useParams()
import { useParams } from 'react-router-dom'
function Detail(){
let {id} = useParams();
console.log(id)
return (
<div className="container">
<div className="row">
<div className="col-md-6">
<img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" />
</div>
<div className="col-md-6 mt-4">
<h4 className="pt-5">{props.shoes[id].title}</h4>
<p>{props.shoes[0].content}</p>
<p>{props.shoes[0].price}원</p>
<button className="btn btn-danger">주문하기</button>
</div>
</div>
</div>
)
useParams()
를 쓰면 /:url파라미터
자리에 사용자가 입력한 값을 읽을 수 있다.
path={ /page/:param1/:/param2 }
와 같이 몇 번이고 올 수 있다.
리액트는 html을 만들어 주는 라이브러리로 대부분 js파일이기 때문에 비슷한 파일끼리 묶어서 한 폴더에 두는게 좋은 폴더 구조일 것이다.
컴포넌트역할의 js 파일은 components 폴더에 묶고
페이지 역할의 js 파일은 routes 또는 pages 폴더에 묶고
자주 쓰는 함수가 있는 js는 utils 폴더에 두면 될 것이다.