아래처럼 세 개의 컴포넌트를 만들어 페이지를 생성하려고 했으나 페이지가 이동되지 않는 오류가 발생했다. 알고 보니 아주 기본적인 설정이었으나 깜빡한 Switch 때문이었다.
// 수정 전
<BrowserRouter>
<Route path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/join" component={Join} />
</BrowserRouter>
// 수정 후
<BrowserRouter>
<Switch>
<Route path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/join" component={Join} />
</Switch>
</BrowserRouter>
3개의 컴포넌트는 path를 통해서 렌더링될 URL이 정해진다. 하지만 세 개의 컴포넌트 모두 /
를 포함하고 있어 일괄적으로 매칭된다. 결국 첫 번째 페이지에서 모든 컴포넌트가 렌더링된다는 문제가 발생한다.
위와 같은 문제점을 해결하기 위해서는 두 가지의 방법이 있다.
exact path
를 사용하여 정확히 일치하는 URL의 컴포넌트를 렌더링시킨다.둘은 첫 번째로 매칭되는 Route만을 바라보느냐 아니냐의 차이다. exact path
를 사용하는 경우는 /
의 컴포넌트를 메인 페이지로 띄울 때다. 정확히 일치하는 경우에만 렌더링하므로 URL이 /
만 포함할 경우 항상 Home 컴포넌트가 렌더링된다.
<BrowserRouter>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/join" component={Join} />
</Switch>
</BrowserRouter>
Switch는 매칭되는 Route가 없을 경우에 띄울 에러 페이지를 따로 설정할 수 있다는 이점이 있다.
<BrowserRouter>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/login" component={Login} />
<Route path="/join" component={Join} />
<Route component={NotFound} />
</Switch>
</BrowserRouter>
문제 해결 이후 react-router-dom의 v6에서는 Switch가 Routes로 바뀌었다는 사실을 알게 됐다. 나는 v5.2.1을 사용하고 있어 Routes를 사용할 수 없고, Switch를 사용해야만 했다.
v6에서 Switch를 이용해 페이지를 이동하려는 경우에는 해당 에러가 발생한다.
'Switch' is not exported from 'react-router-dom'
또한 컴포넌트 연결 시 작성되는 속성인 exact
는 더 이상 사용되지 않으며, component
속성 역시 element
로 작성해야 한다는 점도 유념해야 한다.
// v5
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/join" component={Join} />
</Switch>
// v6
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/join" element={<Join />} />
</Routes>
v6에서는 존재하는 페이지로 접근 시에 띄울 에러 페이지를 어떻게 생성할 수 있을지가 궁금해서 검색해 보았다. path 경로 설정을 *
기호로 입력해 두면 된다.
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/join" element={<Join />} />
<Route path="*" element={<NotFound />} />
</Routes>