SPA 와 라우팅 (history api) | 적용 연습해보기

하영·2024년 12월 9일
1

JavaScript

목록 보기
24/29

SPA와 라우팅

SPA(Single Page Application) 📝

: 웹 애플리케이션 또는 웹사이트의 현대적인 구현 방식

사용자와의 상호작용 중에 웹 페이지를 새로 불러오지 않고, 필요한 데이터만 서버로부터 동적으로 불러와 페이지를 업데이트한다.


라우팅 📝

: 웹 사이트 내에서 URL 을 특정 페이지에 연결하는 과정이라 할 수 있다. 이를 통해 사용자가 브라우저에서 URL을 입력하거나, 링크를 클릭할 때 애플리케이션이 해당 요청에 맞는 적절한 페이지를 반환한다.

→ 특정 웹 주소(URL)의 뒤에 ‘/’ 를 붙여 웹 페이지에 접속하면 브라우저는 해당 주소에 맞는 페이지를 반환할 수 있다.


SPA에서의 라우팅

: 사용자가 페이지, 뷰로 이동할 수 있게 하면서 실제로 전체 페이지를 로드하지 않고 변화가 필요한 요소만을 변경하는 기술

html 파일을 새로 불러오는 것 대신, JavaScript를 사용하여 클라이언트에서 동적으로 필요한 데이터를 불러오고 콘텐츠를 렌더링한다.


History API 와 주요 메서드 📝

: 브라우저가 관리하는 세션 히스토리. → 사용자가 웹 브라우저를 사용해 방문한 페이지들의 목록을 제어할 수 있도록 HTML5가 제공하는 웹 API.

💡 history api 는 메인 스레드 즉, window 에서만 사용할 수 있다.

  • back() : 뒤로가기
  • forward() : 앞으로 가기
  • go() : 탐색 기록에서 상대적인 위치로 이동, (현재 페이지를 다시 로드: 0 | 앞으로가기 : 1 | 뒤로가기 : -1)

history.pushState(state, title, url)

: 페이지 이동 없이 URL 변경 및 새로운 상태 추가 가능

  • state: URL과 연결할 상태 데이터(객체). popstate 이벤트에서 액세스할 수 있음.
  • title: 현재 브라우저는 무시하지만, 향후 사용 가능성을 위해 설정(일반적으로 빈 문자열 사용).
  • url: URL을 설정하며, 이 URL은 반드시 동일 출처이어야 함.

비슷한 역할을 하는 hisory.replaceState(state, title, url) 도 있는데 이는 새로운 데이터로 교체한다. 기존 히스토리를 덮어쓴다는 부분이 pushState와의 차이점이다.

popstate 이벤트

: pushState 또는 replaceState로 탐색 기록이 변경되었을 때, 뒤로 가기/앞으로 가기 버튼을 클릭하면 popstate 이벤트가 발생한다.

window.addEventListener("popstate", (event) => {
  console.log("popstate 이벤트 발생:", event.state);
});
  • event.state: 현재 기록에 연결된 상태 데이터.

코드 연습하기 🚧

<!DOCTYPE html>
<html>
    <head>
        <title>History API</title>
    </head>
    <body>
        <h1>History API 예제</h1>
        <button id="page1">1 페이지 보기</button>
        <button id="page2">2 페이지 보기</button>
        <button id="page3">3 페이지 보기</button>

        <button id="goBack">뒤로 가기</button>
        <button id="goForward">앞으로 가기</button>

        <div id="content">여기에 페이지 내용이 표시됩니다.</div>
        <script src="./src/index.js"></script>
    </body>
</html>

기본 html 구조를 이렇게 작성하고 버튼을 누르면 이동하는 함수 changePage를 작성해보자.

1. changePage 함수 만들기

const changePage = (page) => {
    let content = document.getElementById('content');
    content.textContent = `현재 보고 있는 페이지는 ${page}입니다.`;
};

코드 설명 👩🏻‍💻

  1. 매개변수 page를 받고 idcontent인 document 요소를 가져온다.
  2. 이 요소에 현재 보고 있는 페이지는 ${page}입니다. 텍스트를 입력되도록 한다.

2. changePage 함수 실행하기

const changePage = (page) => {
    let content = document.getElementById('content');
    content.textContent = `현재 보고 있는 페이지는 ${page}입니다.`;
};

document.getElementById('page1').addEventListener('click', () => {
    changePage('page1');
});

document.getElementById('page2').addEventListener('click', () => {
    changePage('page2');
});

document.getElementById('page3').addEventListener('click', () => {
    changePage('page3');
});

(반복된 로직은 잠시 흐린눈 plz 👀)


3. history api 적용하기

const changePage = (page) => {
    let content = document.getElementById('content');
    content.textContent = `현재 보고 있는 페이지는 ${page}입니다.`;
    // ✅ history api 적용
    history.pushState({ page: page }, `Title ${page}`, `/${page}`);
};

pushState 메서드를 사용해서 현재 상태를 추가해주고

const goBack = () => {
    history.back();
};

const goForward = () => {
    history.forward();
};

document.getElementById('goBack').addEventListener('click', goBack);

document.getElementById('goForward').addEventListener('click', goForward);

뒤로 가기, 앞으로 가기 버튼을 눌렀을 때, 페이지 주소들이 변경되도록 코드를 작성한다.


4. 버튼 아래 문구 popstate 사용하여 변경하기

window.addEventListener('popstate', (event) => {
    if (event.state) {
        let content = document.getElementById('content');
        content.textContent = `현재 보고 있는 페이지는 ${event.state.page}입니다.`;
    }
});

pushState를 통해 전달된 객체 event를 매개변수로 받고 idcontent인 요소를 가져와서 문구에 나타나게 만들어주었다.


실습 코드에 적용하기 🚧

(*App.js 파일에서 수정하기~!)

1. TabBar 수정하기

수정할 부분 : onClick 함수에 pushState 메서드로 url 추가하기


2. popstate 이벤트 처리하기 + 반복로직 updateContent로 묶기

popstate 이벤트 발생 → 주소 state 업데이트 필요 (this.state 업데이트 시키기)

👍 how? window.location.pathname 코드 활용!

window.addEventListener('popstate', async () => {
    const tabName = window.location.pathname.replace('/', '') || 'all';

    const photos = await request(tabName === 'all' ? '' : tabName);
    this.setState({
        ...this.state,
        currentTab: tabName,
        photos: photos,
    });
});
  1. this.setState 함수 안에서, 기존의 state 값을 유지하면서, currentTab의 값을 업데이트 시키기
  2. replace() 메서드로 새로운 tabName 값으로 교체하기
  3. api에 전달하는 값이 all 이라면 빈 문자열, tabName 있으면 이 값 전달

3. 맨 위 currentTab 값 수정하기

항상 all 로 설정되어있던 부분을 URL 에 따라 변경되도록 동일하게 window.location.pathname 를 사용하여 수정해주었다.


참고자료

profile
왕쪼랩 탈출 목표자의 코딩 공부기록

0개의 댓글