앞서 만든 상품 페이지에 history API를 적용시켜보자~

- 컴포넌트 구조
App - HomePage
- ProductPage - ProductOptions, Cart
- 페이지 이동 구조
HomePage > ProductPage
- main
import App from "./App.js"; const $app = document.querySelector('.app'); new App({$target : $app})
- App.js
- path 별로 렌더링 처리
- 홈페이지 클릭 이벤트 처리
- 뒤로가기 이벤트 처리
import HomePage from "./pages/HomePage.js"; import ProductPage from "./pages/ProductPage.js"; export default function App({ $target }) { const homePage = new HomePage({$target}); const productPage = new ProductPage({$target, initialState: {}}) this.init = () => { this.route(); } this.route = () => { $target.innerHTML = ''; const currentPath = location.pathname; if (currentPath === "/") { homePage.render(); } else if(currentPath.startsWith("/products/")) { const productId = parseInt(currentPath.split("/products/")[1]) productPage.setState({ productId }) productPage.render() } else { $target.innerHTML = `<h1>404 Error!</h1>` } } window.addEventListener('click', e => { if (e.target.className === "link") { const { href } = e.target; e.preventDefault(); history.pushState(null,'',href.replace(href.origin,'')) this.route(); } }) window.addEventListener('popstate', ()=>this.route()) this.init(); }
- HomePage
- 각 product의 (주문창으로 가는) 링크들을 렌더링
⇒ product를 fetch
import request from "../api/api.js"; export default function HomePage({ $target }) { const $home = document.createElement('div'); this.render = () => { request('/products') .then(products => { $home.innerHTML = ` <h1>Home Page</h1> <ul> ${products.map(product => ` <li> <a class="link" href="/products/${product.id}">${product.name}</a> </li>`).join('')} </ul> ` }) $target.appendChild($home); } }
- ProductPage
- 앞서 만든 것과 동일한 기능
this.setState = (newState) => { if (this.state.productId !== newState.productId) { fetchOptionData(newState.productId) this.state = { ...this.state, ...newState //productId 갱신 } return; } ...