SPA와 라우팅
: 웹 애플리케이션 또는 웹사이트의 현대적인 구현 방식
사용자와의 상호작용 중에 웹 페이지를 새로 불러오지 않고, 필요한 데이터만 서버로부터 동적으로 불러와 페이지를 업데이트한다.
: 웹 사이트 내에서 URL 을 특정 페이지에 연결하는 과정이라 할 수 있다. 이를 통해 사용자가 브라우저에서 URL을 입력하거나, 링크를 클릭할 때 애플리케이션이 해당 요청에 맞는 적절한 페이지를 반환한다.
→ 특정 웹 주소(URL)의 뒤에 ‘/’
를 붙여 웹 페이지에 접속하면 브라우저는 해당 주소에 맞는 페이지를 반환할 수 있다.
: 사용자가 페이지, 뷰로 이동할 수 있게 하면서 실제로 전체 페이지를 로드하지 않고 변화가 필요한 요소만을 변경하는 기술
html
파일을 새로 불러오는 것 대신, JavaScript
를 사용하여 클라이언트에서 동적으로 필요한 데이터를 불러오고 콘텐츠를 렌더링한다.
: 브라우저가 관리하는 세션 히스토리. → 사용자가 웹 브라우저를 사용해 방문한 페이지들의 목록을 제어할 수 있도록 HTML5가 제공하는 웹 API.
💡 history api
는 메인 스레드 즉, window
에서만 사용할 수 있다.
back()
: 뒤로가기forward()
: 앞으로 가기go()
: 탐색 기록에서 상대적인 위치로 이동, (현재 페이지를 다시 로드: 0 | 앞으로가기 : 1 | 뒤로가기 : -1): 페이지 이동 없이 URL 변경 및 새로운 상태 추가 가능
state
: URL과 연결할 상태 데이터(객체). popstate
이벤트에서 액세스할 수 있음.title
: 현재 브라우저는 무시하지만, 향후 사용 가능성을 위해 설정(일반적으로 빈 문자열 사용).url
: URL을 설정하며, 이 URL은 반드시 동일 출처이어야 함.비슷한 역할을 하는 hisory.replaceState(state, title, url)
도 있는데 이는 새로운 데이터로 교체한다. 기존 히스토리를 덮어쓴다는 부분이 pushState
와의 차이점이다.
: 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
를 작성해보자.
const changePage = (page) => {
let content = document.getElementById('content');
content.textContent = `현재 보고 있는 페이지는 ${page}입니다.`;
};
코드 설명 👩🏻💻
page
를 받고 id
가 content
인 document 요소를 가져온다.현재 보고 있는 페이지는 ${page}입니다.
텍스트를 입력되도록 한다.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 👀)
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);
뒤로 가기, 앞으로 가기 버튼을 눌렀을 때, 페이지 주소들이 변경되도록 코드를 작성한다.
window.addEventListener('popstate', (event) => {
if (event.state) {
let content = document.getElementById('content');
content.textContent = `현재 보고 있는 페이지는 ${event.state.page}입니다.`;
}
});
pushState
를 통해 전달된 객체 event
를 매개변수로 받고 id
가 content
인 요소를 가져와서 문구에 나타나게 만들어주었다.
(*App.js 파일에서 수정하기~!)
수정할 부분 : onClick
함수에 pushState
메서드로 url
추가하기
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,
});
});
this.setState
함수 안에서, 기존의 state
값을 유지하면서, currentTab
의 값을 업데이트 시키기replace()
메서드로 새로운 tabName
값으로 교체하기all
이라면 빈 문자열, tabName
있으면 이 값 전달항상 all
로 설정되어있던 부분을 URL 에 따라 변경되도록 동일하게 window.location.pathname
를 사용하여 수정해주었다.
참고자료