// index.html
<!DOCTYPE html>
<head>
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
// index.js
ReactDOM.render(<Router />, document.getElementById("root"));
// Router.js
const Router = () => {
return (
<BrowserRouter>
<Nav />
<Routes>
<Route path="/" element={<App />} />
<Route path="/users" element={<Users />} />
<Route path="/products" element={<Products />} />
<Route path="*" element={<NotFound />} />
</Routes>
<Footer />
</BrowserRouter>
);
};
index.html
: public/index.html에 위치하며 React 페이지 로드 시 가장 먼저 호출되는 영역index.js
: React 앱을 렌더하고 index.html의 div#root
이하에 끼워넣는 역할Router.js
: React 앱이 경로에 따라 어떤 컴포넌트를 보여줄지 결정하는 역할 (화면 바꿔 끼우기)"/" => <App />
"/users" => <Users />
"/products" => <Products />
리스트 페이지
와 해당 아이템의 디테일 한 정보로 구성된상세 페이지
로 구성된다./32692
, /53424
), 해당 id 값에 따라 서로 다른 상세 페이지 정보가 화면에 그려지는 것을 볼 수 있다.// Bad
"/users/1" => <Users id={1} />
"/users/2" => <Users id={2} />
"/users/3" => <Users id={3} />
"/users/4" => <Users id={4} />
"/users/5" => <Users id={5} />
// Good
"/users/:id" => <Users /> // useParams().id
2) Query Parameter
// Bad
"/search?keyword=리액트" : <Search keyword="리액트" />
"/search?keyword=라우팅" : <Search keyword="라우팅" />
"/search?keyword=쿼리스트링" : <Search keyword="쿼리스트링" />
"/search?keyword=SPA" : <Search keyword="SPA" />
// Good
"/search?keyword=something" : <Search /> // useLocation().search
localhost:3000/product/2
localhost:3000/product/45
localhost:3000/product/125
<Router>
<Switch>
<Route exact path='/product/:id' component ={producitDetail} />
</Switch>
</Router>
:
는 Path Parameter가 올 것을 의미id
는 해당 Path Prameter의 이름
1. 카드를 클릭하면, onClick 이벤트시 발생하는 navigate 함수를 통해 /product/1
로 이동. URL 이 /product/1
로 변하면, Router 컴포넌트에 정의되어 있는path='/product/:id'
에 따라, ProductDetail 컴포넌트 마운트
2. ProductDetail 컴포넌트에서는 백엔드에 id 가 1
인 아이템에 대한 정보 요청
3. 응답으로 받은 정보를 setData
함수를 통해 data
라는 state에 저장하고, 이를 통해 상세 페이지 UI가 그려진다.
function Product(props) {
const navigate = useNavigate();
const goToDeatil = () => {
navigate(`/product/${props.id}`);
}
return (
<div className="productContainer" onClick={goToDetail}>
...
</div>
)
}
useNavigate
훅을 실행하면 페이지를 이동시키는(url을 변경시키는) 함수
를 반환한다. 위 예제 코드에서 해당 함수를 navigate
라는 변수에 할당했다. 따라서, navigate()
와 같은 방식으로 함수를 호출할 수 있습니다.navigate()
함수의 인자에 이동하고자 하는 url(ex. /products)을 전달하면, 해당 url로 화면을 이동한다.navigate('/product/1'); // '/product/1' 로 이동
navigate(-1); // 뒤로 가기
navigate(-2); // 뒤로 2페이지 가기
navigate(1); // 앞으로 가기
function ProductDetail(props) {
const location = useLocation();
console.log(location);
return (
...
)
}
useLocation
훅을 실행하면 경로 정보를 담고 있는 객체
를 반환한다. 위 코드에서 해당 객체를 location
이라는 변수에 할당해 주었다. location 변수를 콘솔로 출력해 보면 다음과 같은 로그가 출력 된다.{
pathname: '/product/1', //현재 경로 값
search: '', // 현재 경로의 query parameter 값
hash: '',
state: null,
key: 'default'
}
// 현재경로: /product/1
function ProductDetail(props) {
const params = useParams();
console.log(params);
return(
...
)
}
//반환
{
id: 1 //id 프로퍼티 키 네임은 Router에서 :id로 표기해준 값
}
<BrowserRouter>
<Routes>
<Route path='/product/:id' element={<ProductDetail />} />
</Routes>
</BrowserRouter>
useParam
훅을 이용한다. Path Parameter 로 명시해둔 값은 useParams 훅이 리턴하는 객체에 담기기 때문이다.// ProductDetail.js
// current url -> localhost:3000/product/1
function ProductDetail() {
const params = useParams();
console.log(params.id) // 1
return (
...
);
}
useEffect
훅에서 해당 id
값을 통해 서버에 요청을 보내는 것을 통해 원하는 정보를 받아올 수 있다.useEffect(() => {
fetch(`${API}/${params.id}`)
.then(res => res.json())
.then(res => setData(res));
},[]);
navigate("/product/1")
로 상세 페이지로 이동한다."http://localhost:3000/product/1"
과 같이 변경되어 있다.useParams().id
에서 가져올 수 있다. ```jsx
function ProductDetail() {
const params = useParams();
useEffect(() => {
const productId = params.id;
**fetch(`http://123.456.789:8000/products/${productId}`) // 1**
.then(res => res.json())
.then(res => setData(res));
},[]);
return (
...
)
}
```
res
)를 컴포넌트의 data
state 에 저장해준다.render
해준다.