HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
💌
JJong’s Archive
/
🌞
JS
/
history API 실습 (w. 주문창)

history API 실습 (w. 주문창)

Status
Done
Tags
실습
history
SPA
API
날짜
Oct 18, 2023 03:20 AM
앞서 만든 상품 페이지에 history API를 적용시켜보자~
notion image
 
  • 컴포넌트 구조
    • 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; } ...