<Link /> 컴포넌트를 이용한 페이지 이동React에서는 페이지를 이동할 때는 <a href="/">대신 <Link to="/">를 사용합니다.
<a>태그 대신<Link />컴포넌트를 사용하는 이유는?
<a>태그는Server로 부터 새로운 페이지를 받아오기 때문에 페이지 이동이나 새로고침이 발생할 때 마다 새로 랜더링되기 때문에 상태유지와 속도의 효율성을 위해 새로운 페이지를 불러오는 대신 업데이트하는 방식으로 구현해야 합니다.
-clinet에서 페이지를 처리하는React Routing의Link컴포넌트는HTML history API를 사용하여 브라우저의 주소만 바꿀 뿐 페이지를 새로 불러오지 않습니다.
<Link /> 컴포넌트 실습예제
<a>태그 사용import { BrowserRouter, Route, Switch } from "react-router-dom" import Home from "./pages/Home" import Profile from "./pages/Profile" import About from "./pages/About" import NotFound from "./pages/NotFound.js" function App() { return ( <BrowserRouter> <a href="/">Home</a> <Switch> <Route path="/profile/:id" component={Profile} /> <Route path="/profile" component={Profile} /> <Route path="/about" component={About} /> <Route path="/" exact component={Home} /> <Route component={NotFound} /> </Switch> </BrowserRouter> ) } export default App
결과
Home링크를 클릭하거나 새로고침할때 마다Server로 부터 파일을 새로 받아오기 때문에 네트워크 탭의 파일들을 다시 요청하여 받아옵니다.
<Link />컴포넌트 사용(1)import { BrowserRouter, Route, Switch, Link } from "react-router-dom" import Home from "./pages/Home" import Profile from "./pages/Profile" import About from "./pages/About" import NotFound from "./pages/NotFound.js" function App() { return ( <BrowserRouter> <Link to="/">Home</Link> <Switch> <Route path="/profile/:id" component={Profile} /> <Route path="/profile" component={Profile} /> <Route path="/about" component={About} /> <Route path="/" exact component={Home} /> <Route component={NotFound} /> </Switch> </BrowserRouter> ) } export default App
결과
Link컴포넌트를 사용하면Server로 부터 새로운 파일을 받아 오는것이 아니라 이미client에게 있는 파일중에서 현재 이동하고자 하는 경로에 맞는 페이지를 보여주기 때문에 네트워크 탭의 파일들을 다시Server에게 요청하지 않습니다.
<Link />컴포넌트 사용(2)
Links.js 파일 생성
src폴더안에components폴더를 생성하고components폴더안에 Links.js 파일을 생성 해줍니다.Links.js
import { Link } from "react-router-dom" export default function Links() { return ( <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/profile">Profile</Link> </li> <li> <Link to="/profile/1">Profile/1</Link> </li> <li> <Link to="/about">About</Link> </li> <li> <Link to="/about?name=mark">About?name=mark</Link> </li> </ul> ) }
Links.js파일에<a>태그 대신<Link />컴포넌트를 사용하여 페이지 이동하도록 만듭니다.App.js
import { BrowserRouter, Route, Switch } from "react-router-dom" import Home from "./pages/Home" import Profile from "./pages/Profile" import About from "./pages/About" import NotFound from "./pages/NotFound.js" import Links from "./components/Links" function App() { return ( <BrowserRouter> <Links /> <Switch> <Route path="/profile/:id" component={Profile} /> <Route path="/profile" component={Profile} /> <Route path="/about" component={About} /> <Route path="/" exact component={Home} /> <Route component={NotFound} /> </Switch> </BrowserRouter> ) } export default App
App.js파일에서Links.js파일을import한뒤<Links />컴포넌트를 추가 해줍니다.
결과
http://localhost:3000
http://localhost:3000/profile/1
http://localhost:3000/about?name=mark
- 해당 링크로 클릭하여 이동할때마다 페이지 파일들이 새로 로딩되지 않고
React컴포넌트의 뷰만 새로 바뀌어 보여줍니다.
<NavLink /> 컴포넌트를 이용한 페이지 이동import {NavLink} from "react-router-dom";activeClassName, activeStyle 처럼 active 상태에 스타일 지정이 가능합니다.Route의 path처럼 동작하기 때문에 exact가 있습니다.
<Link />컴포넌트와<NavLink />컴포넌트의 차이점
- 공식문서에 아래와 같이
NavLink컴포넌트는Link의special version이라고 명시 되어 있다.
- 특정 링크에 스타일을 넣어 줄 수 있다.
- 이것이 바로
Link와NavLink의 가장 큰 차이점이다.
조금 더 특별한 기능이란?
- 바로
activeStyle과activeClassName속성이다.- 리액트 웹의 현재
URL과to가 가리키는 링크가 일치할 때,activeStyle과activeClassName이 활성화 되고 일치하지 않으면 비활성화가 된다.
<NavLink /> 컴포넌트 실습예제App.js
import { BrowserRouter, Route, Switch } from "react-router-dom" import Home from "./pages/Home" import Profile from "./pages/Profile" import About from "./pages/About" import NotFound from "./pages/NotFound.js" import Links from "./components/Links" import NavLinks from "./components/NavLinks" function App() { return ( <BrowserRouter> <Links /> <NavLinks /> <Switch> <Route path="/profile/:id" component={Profile} /> <Route path="/profile" component={Profile} /> <Route path="/about" component={About} /> <Route path="/" exact component={Home} /> <Route component={NotFound} /> </Switch> </BrowserRouter> ) } export default App
activeStyle
activeStyle에는active된 링크에 적용할 스타일을 정의 합니다.
NavLinks.js_(activeStyle)
import { NavLink } from "react-router-dom" const activeStyle = { color: "red" } export default function NavLinks() { return ( <ul> <h1>NavLink</h1> <li> <NavLink to="/" exact activeStyle={activeStyle}> Home </NavLink> </li> <li> <NavLink to="/profile" exact activeStyle={activeStyle}> Profile </NavLink> </li> <li> <NavLink to="/profile/1" activeStyle={activeStyle}> Profile/1 </NavLink> </li> <li> <NavLink to="/about" activeStyle={activeStyle}> About </NavLink> </li> <li> <NavLink to="/about?name=mark" activeStyle={activeStyle}> About?name=mark </NavLink> </li> </ul> ) }결과
http://localhost:3000/about
About만 빤간색으로 출력되어야 하지만/About?name=mark도 같이 빨간색으로 출력되는것을 볼 수 있습니다.
Location
location객체에는 현재 페이지의 정보를 가지고 있습니다.http://localhost:3000/profile/1
pathname:[string]현재 페이지의 경로명search:[string]현재 페이지의query stringhash:[string]현재 페이지의hash
NavLinks.js_(Location)
import { NavLink } from "react-router-dom" const activeStyle = { color: "red" } export default function NavLinks() { return ( <ul> <li> <NavLink to="/" exact activeStyle={activeStyle}> Home </NavLink> </li> <li> <NavLink to="/profile" exact activeStyle={activeStyle}> Profile </NavLink> </li> <li> <NavLink to="/profile/1" activeStyle={activeStyle}> Profile/1 </NavLink> </li> <li> <NavLink to="/about" activeStyle={activeStyle} isActive={(match, location) => { console.log(location) return location.search === "" //isActive 함수 true 반환시 특정스타일주기 }} About </NavLink> </li> <li> <NavLink to="/about?name=mark" activeStyle={activeStyle} isActive={(match, location) => { return location.search === "?name=mark" //isActive 함수 true 반환시 특정스타일주기 }} About?name=mark </NavLink> </li> </ul> ) }
isActive속성은boolean데이터true/false를 반환하며router의 현재 상태를 알 수 있습니다./about과/about?name=mark에는isActive함수로true값을 반환하면activeStyle을 실행합니다.
/about일때는search: ""인것을 볼 수 있습니다.
- 반면에
about?name=mark일때는search: "?name=mark"인것을 볼 수 있습니다.
결과
http://localhost:3000/about
isActive속성으로/about은search: "",about?name=mark는search: "?name=mark"일때만true로return하므로/about과about?name=mark이 둘다 빨간색으로 출력되지 않습니다.
http://localhost:3000/profile/1
하지만
/profile/1로 이동하면Profile/1과/About이 모두 빨간색으로 출력됩니다.
Match
match객체에는<Route path>와URL이 매칭된 대한 정보가 담겨져 있습니다.http://localhost:3000/about
path:[string]라우터에 정의된pathurl:[string]실제 클라이언트로부터 요청된url pathisExact:[boolean]true일 경우 전체 경로가 완전히 매칭될 경우에만 요청을 수행params:[JSON object]url path로 전달된 파라미터 객체
NavLinks.js_(Match)
import { NavLink } from "react-router-dom" const activeStyle = { color: "red" } export default function NavLinks() { return ( <ul> <h1>NavLink</h1> <li> <NavLink to="/" exact activeStyle={activeStyle}> Home </NavLink> </li> <li> <NavLink to="/profile" exact activeStyle={activeStyle}> Profile </NavLink> </li> <li> <NavLink to="/profile/1" activeStyle={activeStyle}> Profile/1 </NavLink> </li> <li> <NavLink to="/about" activeStyle={activeStyle} isActive={(match, location) => { console.log(match, location) return match !== null && location.search === "" }} About </NavLink> </li> <li> <NavLink to="/about?name=mark" activeStyle={activeStyle} isActive={(match, location) => { return match !== null && location.search === "?name=mark" }} About?name=mark </NavLink> </li> </ul> ) }결과
http://localhost:3000/Profile/1
/Profile/1로 페이지 이동을 하면match객체가null로 표시되는 것을 볼 수 있습니다.http://localhost:3000/about
/about페이지로 이동하면match객체가null이 아닌 객체로 표시되는 것을 볼 수 있습니다.http://localhost:3000/profile/1
- 이제는
/profile/1로 이동해도Profile/1만 빨간색으로 출력되는 것을 볼 수 있습니다.- 그 이유는
/about페이지에return match !== null && location.search === ""를 설정하여match가null값이 아니면서location.search가""일 경우에만activeStyle가 실행되기 때문입니다.