1. 가장 간단한 예시.
---> 무슨 버튼 하나 클릭하면 홈 페이지에서 about이라는 상세 페이지로 이동할 수 있게 하는 코드이다.
import React from 'react';
import {BrowserRouter as Router, Route, Routes, useNavigate} from 'react-router-dom'
function About() {
return <h1>About Page</h1>;
}
function Home() {
const navigate = useNavigate();
const goToAbout = () => {
navigate('/about');
};
return (
<div>
<h1>Home Page</h1>
<button onClick = {goToAbout}>Go to About</button>
</div>
);
}
function App(){
return (
<Router>
<Routes>
<Route path="/" element={<Home/>}></Route>
<Route path="/about" element={<About />} />
</Routes>
</Router>
);
}
export default App;
useNavigate를 사용하기 위해서 꼭 필요한 세 가지 컴포넌트에 대한 설명은 다음과 같다.
1. function App은 Router를 설정하는 컴포넌트이다.
- BrowserRouter를 불러와서 라우터를 설정하고, Routes안에 Route를 사용하여 path= "이동할 경로" element ={<이동할 경로에 렌더링 될 컴포넌트 />} 를 Route 블럭 안의 인자로 전달한다.
- <Route>는 여러 개를 작성해도 된다.
2. function Home은 초기 화면을 보여주는 컴포넌트이다.
- 여기서 useNavigate 훅을 이용해서 navigate 함수를 설정한다.
- 그리고 const goToAbout 함수에서 navigate 함수 안에 이동할 경로의 주소( 여기서는 '/about' ) 를 적어준다.
- 이 예제에서는 goToAbout 함수 자체는 아무 변수도 전달받지 않았는데, 여기서 어떤 변수를 전달하고 그 변수 값에 따라서 이동할 주소(navigate함수의 변수)가 달라지게 하면 동적인 라우팅이 되는 것이다.
그리고 Home 컴포넌트는
1. Home Page라는 제목 텍스트
2. 클릭하면 goToAbout 함수가 실행되는 버튼을 리턴값으로 갖는다.
이 두 개는 실제로 html처럼 화면에 렌더링되고, 버튼을 클릭하면 goToAbout 함수의 navigate함수가 받은 매개변수로 경로가 변경된다.
3. function About은 /about 경로에 가면 표시되는 컴포넌트이다.
- 간단한 예제이므로 내용은 h1으로 About Page라는 텍스트만 띄우는 페이지이다.
2. 리스트 페이지에서 상세 페이지로 이동하는 예시
위의 예시와 마찬가지로
1. 루트를 설정하는 컴포넌트
2. 리스트가 표시되는 홈 컴포넌트
3. 상세 페이지 컴포넌트
이렇게 세 개가 필요하다.
/*app.js,라우팅하는 곳*/
import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Home from './Home';
import MovieDetail from './MovieDetail';
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/movie/:title" element={<MovieDetail />} />
</Routes>
</Router>
);
}
export default App;
/*이게 홈 컴포넌트*/
import React from 'react';
import {useNavigate} from 'react-router-dom';
function Home() {
const navigate = useNavigate();
const movies = [
{title: 'Movie1', name: 'Movie 1'},
{title: 'Movie2', name: 'Movie 2'},
];
const goToMovieDetail = (title) => {
navigate(`/movie/${title}`);
};
return (
<div>
<h1>Movie List</h1>
<ul>
{movies.map((movie) => (
<li key={movie.title} onClick={() => goToMovieDetail(movie.title)}>
{movie.name}
</li>
))}
</ul>
</div>
);
}
/*이게 상세 페이지 컴포넌트*/
import React, {useEffect, useState} from 'react';
import {useParams} from 'react-router-dom';
import axios from 'axios';
function MovieDetail() {
const {title} = useParams();
const [movie, setMovie] = useState(null);
useEffect(() => {
async function fetchMovie() {
try {
const response = await axios.get('https://api.example.com~~/${title}');
//const {title} = useParams(); 에서 추출한 'title'을 사용하여 해당 영화의 정보를 가져오는 api호출을 수행한다.
setMovie(response.data);
} catch (error) {
console.error('Error fetching movie details:', error);
}
}
fetchMovie();
}, [title]);//useEffect의 의존성배열에 title이 있으므로, useEffect훅 안의 함수는 1. 마운트(처음렌더링)될 때, 2.title이 변경될 때마다 실행된다.
if (!movie) {
return <div>Loading...</div>;
}
return (
<div>
<h1>{movie.title}</h1>
<p>{movie.description}</p>
{/* 추가적인 영화 정보 표시 */}
</div>
);
}
export default MovieDetail;
위에서는 useparams로 타이틀 정보 한 개만 불러왔는데,
나는 사진, 제목, 평점, 개봉일, 줄거리 등 더 많은 파라미터를 detail page에 불러오고 싶다.
이런 경우에는 일반적으로 주요 식별자(제목 등)은 useParams를 사용하여 경로 파라미터로 처리하고,
부가 정보나 선택적 정보는 'useLocation'을 사용하여 쿼리 파라미터로 처리하는 게 좋다고 한다.
이유가 뭘까??
useParams와 useLocation의 차이
1. useParams
- 구현하고 읽기에 더 쉽고, 직관적이다.
2. useLacation
- 여러 개의 쿼리 파라미터를 한 번에 처리하거나, 선택적으로 처리할 때 유용하다.
- url의 전체 정보를 객체로 불러올 수 있어서 동적 경로 설정 이외에도 검색이나 필터링 등 다양한 기능을 구현할 수 있다.
3. 많은 파라미터를 처리해야 할 때는 useLocation이 더 좋다.
쿼리 파라미터의 장점:
쿼리 파라미터는 선택적이므로 파라미터가 없는 경우에도 기본 url이 작동한다.
그래서 파라미터를 유연하게 추가하고 제거할 수 있다. 쿼리파라미터는 순서도 상관이 없다.
반면에 많은 파라미터를 경로 파라미터로 사용하면 URL이 길어지고 복잡해진다. 또한 파라미터 순서에 의존하게 되어 관리가 어려울 수 있고, 경로의 일부분이 빠지면 URL이 작동하지 않을 수 있다.
4. 주요 식별자 정보 가져올 때는 useParams가 더 좋다.
경로 파라미터로 주요 식별자 정보를 가져오면 좋은 점:
URL의 구조를 명확하게 하고, RESTful 원칙을 준수하며, 코드의 간결성과 가독성을 높일 수 있다.
결론)
- 그래서 파라미터가 많을 때는 보통 useParams로 가져오는 경로 파라미터로 주요 식별자 정보를 전달하고, useLocation으로 가져오는 쿼리 파라미터로 부가 정보를 전달하는 것이 좋다.
- 예를 들면 영화의 제목은 useParams로, 그 외 개봉일, 평점, 줄거리 등은 useLocation으로 받아오는 것이 좋다고 한다.
3. 결론적으로 두가지 다른 방법으로 url에서 파라미터 추출하는 훅을 모두 이용해서,
간단하게 title은 useParams를, release_date는 useLocation을 사용해서 불러오는
detail page의 예시 코드는 다음과 같다.
import React, {useEffect, useState} from 'react';
import {useParams, useLocation} from 'react-router-dom';
import axios from 'axios';
function MovieDetail() {
const {title} = useParams();
const location = useLocation();
//useLocarion 훅은 현재 url의 위치 정보를 반환한다. 다양한 url정보가 포함됨.
const queryParams = new URLSearchParams(location.search);
const release_date = queryParams.get('release_date'); //이때 이제 release_date를 가져오게 되는 것이다.
const [movie, setMovie] = useState(null);
useEffect(() => {
async function fetchMovie() {
try {
const response = await axios.get(`http://api.example.어쩌구저쩌구`)
setMovie(response.data);
}catch (error){
console.error('Error fetching movie details:' , error);
}
}
fetchMovie();
}, [title]);
if (!movie) {
return <div>Loading...</div>;
}
return (
<div>
<h1>{movie.title}</h1>
<p>개봉일: {release_date}</p>
</div>
);
}
export default MovieDetail;
'WEB > React' 카테고리의 다른 글
[React] Router v5에서 v6으로 가면서 바뀐 것 (0) | 2024.05.22 |
---|---|
[React] useLocation 훅 이해하기 (0) | 2024.05.22 |
React - useState과 useEffect (0) | 2024.05.15 |
Synchronous(동기), Asynchronous(비동기) (0) | 2024.05.15 |
[React] 함수형 컴포넌트와 클래스형 컴포넌트, useEffect는 어떨 때 쓸까? (0) | 2024.05.15 |