React/React Router

[React Router]<Link> 태그 Issue 해결하기

Rayched 2024. 2. 13. 01:37

1. 문제  설명

영화 App 실행 예시

 

위의 이미지와 같은 특정 날짜를 기준으로, 주간 박스 오피스 정보를 출력하는 웹 페이지에서

영화 제목을 클릭하면, 해당 영화에 대한 상세 정보가 적힌 웹 페이지로 넘어가는 기능을

React Router를 활용해서 구현하고 정상적으로 동작하는 지 테스트를 해봤다.

 

더보기

'Home.js' (영화 웹 페이지의 기본 화면 담당)

 

import { useState } from "react";
import { useEffect } from "react";

import Movie from "../Components/Movie";

function Home(){
    const [Loading, setLoading] = useState(true);
    const [Movies, setMovies] = useState([]);

    const getMovies = async() => {
        const response = await fetch(
        "http://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchWeeklyBoxOfficeList.json?key=3a15c5393ac14d11f6b132d6a07f330c&targetDt=20240131"
        );
        const json = await response.json();
        setMovies(json.boxOfficeResult.weeklyBoxOfficeList);
        setLoading(false);
    }

    useEffect(() => {
        getMovies();
      }, []);
    
      useEffect(() => {
        if(Movies.length === 0){
          return;
        } else {
          console.log(Movies)
        }
      }, [Movies]);
    
    return (
        <div>
            {
                Loading ? <h3>주간 박스 오피스 데이터를 가져오는 중...</h3>
                :<div>
                { 
                    Movies.map((movie) => { 
                    return (
                        <Movie
                        key={movie.movieCd}
                        MovieName={movie.movieNm} 
                        openDate={movie.openDt} 
                        AudiCount={movie.audiAcc}
                        />);
                    })}
                </div>
            }
        </div>
    );
}

export default Home;

Movie.js (영화 제목 클릭 시, Rendering되는 Component)

 

function MovieDetail(){
	return (
    	<div>
        	<h4>Detail</h4>
        </div>
    );
}

export default MovieDetail;

App.js

import {
    BrowserRouter as Router,
    Route,
    Switch
} from "react-router-dom";

import Home from "./routes/Home";
import MovieDetail from "./routes/MovieDetail";

function App(){
	return (
    	<Router>
        	<Switch>
        		<Route path="/movie">
          			<MovieDetail />
        		</Route>
        		<Route exact path="/">
          			<Home />
        		</Route>
      		</Switch>
        </Router>
    );
}

export default App;

예제 실행 결과 / 실제로 나와야 하는 결과

 

예제를 실행하면 처음 이미지와 같이 주간 박스 오피스 정보가 웹 페이지에 표시되고

이 상태에서 영화 제목을 클릭하면 'Detail'이라고 적힌 웹 페이지로 넘어가져야만 한다.

 

하지만 실제로 영화 제목을 클릭했을 때, URL은 "/movie"로 변경됐지만, 웹 페이지는 갱신이 안된다.

물론 "/movie" URL을 입력하면 문제없이 잘 넘어가진다.

 

React-router<Link> 태그와 관련된 부분에서 문제가 생겼다고 볼 수 있다.


2. 문제의 원인과 해결 과정

위와 같이 React Router의 <Link> 태그가 정상적으로 작동하지 못하게 된 이유는

현재 사용 중인 'create-react-app'과 'react-router-dom' 5.3 버전이 충돌을 일으켰기 때문이다.

(강의에서 React Router를 설치한 버전과 같은 버전으로 설치하였음)

 

그리고 이러한 충돌 이슈는 react-router-dom을 최신 버전으로 업데이트해서 손쉽게 해결할 수 있다.

아래 명령어를 입력해서 react-router-dom을 최신 버전으로 업데이트를 진행하였다.

 

npm install react-router-dom@latest
npm i react-router-dom@latest

 

react-router-dom이 정상적으로 업데이트 됐는 지를 확인하고 싶다면

'package-lock.json' 파일을 띄우고 그 상태에서 'Ctrl + F 누르면 검색 창을 띄울 수 있다.

'react-router-dom'을 입력하면, 현재 프로젝트 폴더에 설치된 react-router-dom의 버전을 확인할 수 있다.

 

react-router-dom 버전 확인

 

그리고 추가적으로 react-router-dom 버전 6부터 달라진 점이 있다고 하여

이에 맞춰서 'App.js' 파일의 App 함수 코드도 좀 수정을 해줘야 한다.

('App.js'의 소스코드는 앞 장의 '접은 글'을 참조할 것)  

 

react-router-dom 버전 6부터 <Switch> 태그는 더이상 사용되지 않으며
대신 <Switch> 태그가 수행하던 역할은 <Routes> 태그가 대신 수행하게 된다.

추가적으로 <Routes> 태그가 최적의 경로 배정을 하기 때문에
path 속성의 값과 입력된 URL 값이 정확하게 일치할 때만 하위 요소를 Rendering 시키던
<Route> 태그의 exact 속성도 사용되지 않는다고 한다.

그리고 이제 <Route> Component 사이에 자식 Component를 추가하지 않고
대신에 'element' 속성에 자식 Component를 값으로 전달하도록 바뀌었다.

React Router 공식 문서 참조

 

import {
    BrowserRouter as Router,
    Route,
    //Switch,
    Routes,
} from 'react-router-dom';

import Home from "./routes/Home";
import MovieDetail from "./routes/MovieDetail";

function App(){
	return (
        <Router>
            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/movie" element={<MovieDetail />} />
            </Routes>
        </Router>
    );
}

export default App;

 

위와 같이 'App' 함수의 코드를 업데이트하고, 예제에서 영화 제목을 클릭하면

아래와 같이 'Detail'이라고 적힌 웹 페이지로 정상적으로 넘어가지는 것을 확인할 수 있다.

영화 제목을 클릭하면, Detail이라고 적힌 웹 페이지로 넘어간다.


📔 Reference

공식 문서
ReactJS로 영화 웹 서비스 만들기