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;

 

+ Recent posts