React[Router] - JSX링크로 라우팅 이동하기

일상 코딩·2022년 6월 1일
0

React

목록 보기
25/45
post-thumbnail
post-custom-banner
  • React에서는 페이지를 이동할 때는 <a href="/">대신 <Link to="/">를 사용합니다.

<a>태그 대신 <Link /> 컴포넌트를 사용하는 이유는?

  • <a> 태그는 Server로 부터 새로운 페이지를 받아오기 때문에 페이지 이동이나 새로고침이 발생할 때 마다 새로 랜더링되기 때문에 상태유지와 속도의 효율성을 위해 새로운 페이지를 불러오는 대신 업데이트하는 방식으로 구현해야 합니다.
    -clinet에서 페이지를 처리하는 React RoutingLink 컴포넌트는 HTML history API를 사용하여 브라우저의 주소만 바꿀 뿐 페이지를 새로 불러오지 않습니다.

<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 컴포넌트의 뷰만 새로 바뀌어 보여줍니다.

  • import {NavLink} from "react-router-dom";
  • activeClassName, activeStyle 처럼 active 상태에 스타일 지정이 가능합니다.
  • Routepath처럼 동작하기 때문에 exact가 있습니다.

<Link /> 컴포넌트와 <NavLink /> 컴포넌트의 차이점

  • 공식문서에 아래와 같이 NavLink 컴포넌트는 Linkspecial version 이라고 명시 되어 있다.
  • 특정 링크에 스타일을 넣어 줄 수 있다.
  • 이것이 바로 LinkNavLink의 가장 큰 차이점이다.

조금 더 특별한 기능이란?

  • 바로 activeStyleactiveClassName 속성이다.
  • 리액트 웹의 현재 URLto가 가리키는 링크가 일치할 때, activeStyleactiveClassName이 활성화 되고 일치하지 않으면 비활성화가 된다.

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 string
  • hash : [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 속성으로 /aboutsearch: "", about?name=marksearch: "?name=mark"일때만 truereturn하므로 /aboutabout?name=mark이 둘다 빨간색으로 출력되지 않습니다.

  • http://localhost:3000/profile/1

  • 하지만 /profile/1로 이동하면 Profile/1/About이 모두 빨간색으로 출력됩니다.

Match

  • match 객체에는 <Route path>URL이 매칭된 대한 정보가 담겨져 있습니다.
  • http://localhost:3000/about
  • path : [string] 라우터에 정의된 path
  • url : [string] 실제 클라이언트로부터 요청된 url path
  • isExact : [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 === ""를 설정하여 matchnull값이 아니면서 location.search""일 경우에만 activeStyle가 실행되기 때문입니다.
profile
일취월장(日就月將) - 「날마다 달마다 성장하고 발전한다.」
post-custom-banner

0개의 댓글