상세 컨텐츠

본문 제목

React(리액트) 티키타카 37 (Route 이해)

React

by e7e 2025. 5. 16. 00:23

본문

오늘은 HJ의 요청으로 리액트 라우터에 대해 이야기를 구찌스럽게 해보려 한당.

먼저 form 전송 방식이 아닌, 데이터 관련 한 것만 B/E 서버와 비동기 AJAX로 통신하는

SPA(Single Page Application) 기준으로 보면 구찌 주소표시줄 URL을 관리하는 

라우터가 필요한가 의구심이 들 수도 있당. (의구심이 들었다면 오히려 감각이 뛰어나미당!) 

AJAX에 쓰는 URL은 주소 표시줄에 나타나지 않고, 나타낼 필요도 없음이당.

SPA란 것이 최종 사용자 입장에선 거의 데스크탑 앱 느끼미당.

하지만 이미 최종 사용자들은 URL 자체를 즐겨찾기에 저장하거나, URL을 보고 본인이

어디에 있는지를 아는 사람들도 있기 때문에 새로운 환경을 만들기 전까지는 URL 관리가

필요함을 인지 하지 아니 하지 않을 수 업스미당. (인지 할 수 없다면 그건 왜 인지??)

 

react-router는 react에서 제공되지 않아서 별도 (3rd-party) 로 설치해야 한당.

 

react-router를 설치해서 사용해 보기 전에, 핵심 컴포넌트인 Link와 Route를 미리

대략적으로 만들어 보는 시간을 가져, 실제 사용시에 발생할 수 있는 궁금증 폭발

사전에 어느정도 예방 할 수 있는 시간을 구찌 가져 보장.

미리 정리하자면, 결과적으로는 Tab 컴포넌트를 만드는 것과 거의 유사하당.

 

먼저 Link당, Link는 아래 형태로 사용된당.  props에 to 와 children이 너머 와야 한당.

 <Link   to={"/"}  ></Link>

 

그렇다면 만들어 보장.

Link.jsx

function Link({ to, children }) {
  const preventNavi = (event) => {
    event.preventDefault();
    history.pushState({}, "", to);
    const naviEvent = new PopStateEvent("navi", {
      state: { name: "메롱" },
    });
    window.dispatchEvent(naviEvent);
  };
 
  return (
    <a href={to} onClick={preventNavi}>
      {children}
    </a>
  );
}
 
export default Link;

기본적으로 a 태그의 href 속성은 서버에 get 요청을 보내므로, 못 보내게 preventDefault로 막았다.

주소 표시줄 값 변경이 필요하다. history 객체의 pushState를 이용하였다.

변경이 일어났다는 사실을 다른 컴포넌트가 알 수 있도록 이벤트를 발생 시키장.

원래 브라우져의 앞으로/뒤로 이벤트는 popstate 이벤트를 발생시킨당.

PopStateEvent를  navi란 이름으로 만들었다.

두번째 매개변수는 이벤트에 담기는 값인데, 그냥 괘니 넣었다. 재미당.

dispatchEvent 메소드를 이용하여 강제로 만든 이벤트를 발생시켰당.

 

이제 Route 컴포넌트를 만들어 보장.

Link 컴포넌트에서 발생되는 이벤트에 맞춰 화면에 출력할지 

말지를 결정해 주는 컴포넌트가 될 것이다. 이것이 핵심이당. 

 

Route.jsx

/* eslint-disable react-hooks/exhaustive-deps */
import { useCallback, useEffect, useState } from "react";
 
function Route({ path, element }) {
  const [curPath, setCurPath] = useState(location.pathname);
 
  const onLocChange = useCallback((e) => {
    console.log("체킁:", e, path);
    setCurPath(location.pathname);
  }, []);
 
  useEffect(() => {
    window.addEventListener("navi", onLocChange);
 
    return () => {
      window.removeEventListener("navi", onLocChange);
    };
  }, []);
 
  console.log("체킁:", curPath, path);
 
  return curPath === path ? element : null;
}
 
export default Route;

location.pathname 하면 현재 주소 표시줄의 값을 가져오는데, 현재 값이

http://merong:8282/manse 라면  /manse만 가져온당.

Link를 클릭하면 navi 이벤트가 발생시키므로, navi 이벤트가 발생할 때마다

현재 주소 표시줄 값과 path를 비교할거당.

비교하여 같다면, 넘겨받은 element를 return 한당.

다르다면 null을 return 한당.

곧 여러개의 Route가 있는데, 그중 주소 표시줄 값과 일치하는 Route만

자신이 넘겨 받은 element를 화면에 출력하고, 나머지는 안 출력된당.

 

적용을 위해 간단히 Idol 컴포넌트 1개만 만들장.

사실 간단한 거 여러개 만드는 게 이해엔 더 도움이 된당.(미안탕~~)

Idol.jsx

function Idol({name,good}) {
  return (
    <div style={{background:"skyblue"}}>
       <h1>이름: <span style={{color:"blueviolet"}}>{name}</span></h1>
       <h1>특기: <span style={{color:"#db8726"}}>{good}</span></h1> 
    </div>
  )
}

export default Idol

 

이제 적용하여 보장

App.jsx

import Idol from "./Idol"
import Link from "./Link"
import Route from "./Route"

function App() {


  return (
    <div style={{width:"60%",margin:"5px auto"}}>
      <h1>현정 라우터 이해</h1>
      <hr />
      <div style={{display:"flex",justifyContent:"space-between"}}>
        <Link to={"/kmn"}>경미니</Link>
        <Link to={"/arn"}>아리니</Link>
        <Link to={"/smn"}>수미니</Link>
      </div>
      <hr />
      <div>
        <Route path={"/kmn"} element={<Idol name={"경미니"} good={"기획 천재"} />} />
        <Route path={"/arn"} element={<Idol name={"아리니"} good={"코딩 천재"} />}/>
        <Route path={"/smn"} element={<Idol name={"수미니"} good={"피그마 천재"} />}/>
      </div>
    </div>
  )
}

export default App

나의 경우 아래와 같은 결과와 눈맞춤이당.

동작 모습은 거의 Tab 컴포넌트당.

이해되었기를 간절히 졸리운 눈으로 하늘을 본당. 흐리당.

 

온 김에 쪼메 더 가보장.

Link에 style이나 className 속성을 가지고, 해당 속성에 콜백함수를 작성하여

isActive 상태를 매개변수로 넘겨 받을 수 있는 NavLink가 있당.

그것도 대략 한번 괘니 혹 즐거울지도 모르닝, 맹글어 보장.

 

NavLink.jsx

/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useState } from "react";

function NavLink({ to, children, style: myStyle }) {
  const [isActive, setIsActive] = useState(false);

  const preventReload = (event) => {
    event.preventDefault();
    history.pushState({}, "", to);
    const naviEvent = new PopStateEvent("navi", {
      state: { name: "경미니 메롱" },
    });
    window.dispatchEvent(naviEvent);
  };

  useEffect(() => {
    setIsActive(to === location.pathname);
    window.addEventListener("navi", () => {
      setIsActive(to == location.pathname);
    });
  },[]);

  return (
    <div
      style={{
        display: "inline-block",
        width: "30%",
        fontSize: "1.5em",
      }}
    >
      <a
        href={to}
        style={myStyle ? myStyle(isActive) : {}}
        onClick={preventReload}
      >
        {children}
      </a>
    </div>
  );
}

export default NavLink;

매개변수 구조분해  { to, children, style:myStyle } 에서 

style 속성에 쓰여진 콜백함수를 myStyle로 받는 부분이 핵심이당.

jsx안에서 style은 keyword라서 임의로 myStyle로 바꾸었당.

나머진 보면 알 수 있당. 다시 적용해 보장.

 

App.jsx

import Idol from "./Idol"
import NavLink from "./NavLink"
import Route from "./Route"

function App() {


  return (
    <div style={{width:"60%",margin:"5px auto"}}>
      <h1>현정 라우터 이해</h1>
      <hr />
      <div style={{display:"flex",justifyContent:"space-between"}}>
        <NavLink to={"/kmn"} style={(isActive)=> isActive?{"color":"#db8726"}:{}}>경미니</NavLink>
        <NavLink to={"/arn"} style={(isActive)=> isActive?{"color":"#db8726"}:{}}>아리니</NavLink>
        <NavLink to={"/smn"} style={(isActive)=> isActive?{"color":"#db8726"}:{}}>수미니</NavLink>
      </div>
      <hr />
      <div>
        <Route path={"/kmn"} element={<Idol name={"경미니"} good={"기획 천재"} />} />
        <Route path={"/arn"} element={<Idol name={"아리니"} good={"코딩 천재"} />}/>
        <Route path={"/smn"} element={<Idol name={"수미니"} good={"피그마 천재"} />}/>
      </div>
    </div>
  )
}

export default App

결과는 눈앞에 요렇게 찾아왔당.

이제 클릭한 링크만 색깔이 다름을 볼수 있당. Link 와NavLink의 차이당.

이걸 이해했다면 className에 콜백함수를 넣는 것도 무조건 만들수 있어야 한당.

그렇지 못하다면?...  No Comment 하겠당.

 

필요하다면 가져가셔도... 가져 간 것도 난 모름지기

hj-router.zip
0.04MB

 

리액트 라우터

자바스크립트 이벤트 리스트

 


코드가 스스로 춤추기 시작할 때

그 때 코드는 스스로 다이아몬드가 되었당.~~

 

https://www.youtube.com/watch?v=v0Ul6eCyLhg

 

관련글 더보기