본문 바로가기
JS/React

SPA Route

by kiberd 2022. 10. 6.

일반적으로 spa에서 라우팅 구현은  window history 객체에 있는 pushState로 구현한다.

history 객체에서 주소창을 바꾸는 메소드는 replaceState, pushState 2가지가 존재한다. 차이점은 replaceState는 뒤로가기가 활성화 되지 않고 주소창이 말 그대로 replace되는 것이며, pushState는 스택처럼 history가 쌓이는 구조이다.

그래서 spa구조에서 실제 라우팅 되는 것처럼 구현을 하려면 pushState를 사용해야 한다.

(location.replace 는 아예 새로 페이지를 그리는 것이기 때문에 불가)

pushState(state, unused, url)

문법은 다음과 같다. 전달하고 싶은 상태값을 state에 넣어주고, 변경하길 원하는 주소값을 url에 넣어준다.

다음은 이것을 응용하여 구현한 push기능을 가지고 있는 useRouter 이다.

import React, { useContext } from "react";
import RouterContext from "./context/RouterContext";

const useRouter = () => {

    const { setLocation } = useContext(RouterContext);

    const push = (path) => {
        window.history.pushState({ path }, null, path);
        setLocation(path);
    }
    return { push };
    
};

export default useRouter;

해당하는 경로를 history state에 저장해주고, 전역적으로(Router)에 저장되어있는 location state에 해당 경로를 저장해준다.

그러면 Router에서 들고 있는 location 값이 바뀌게 되면서 해당하는 컴포넌트가 렌더링 되게 된다.

import React, { useState, useEffect, createContext } from "react";
import RouterContext from "./context/RouterContext";

const Router = ({ children }) => {
  const [location, setLocation] = useState(window.location.pathname);

  useEffect(() => {
    window.addEventListener("popstate", (e) => {
      setLocation(e.state.path);
    });
  }, []);

  return (
    <RouterContext.Provider
      value={{
        location,
        setLocation,
      }}
    >
      {children}
    </RouterContext.Provider>
  );
};

export default Router;
 

또한, 뒤로가기 버튼을 누를때 발생되는 이벤트인 popstate 핸들러를 통해 history 객체에 저장되어 있는 path state를 가져와 해당하는 location을 다시 설정해준다.

'JS > React' 카테고리의 다른 글

useQueryDebounce  (0) 2022.09.05
Closure로 useEffect hook 구현  (0) 2021.12.27
React Lazy Loading  (0) 2021.12.22