FrameWork/FastAPI

Svelte Store

mansoorrr 2024. 6. 4. 19:33

앞에서 페이지 네이션을 구현했다. 문제가 있다. 원하는 페이지로 넘어가서 질문을 클릭하면 세부페이지로 이동하게 된다. 이후 다시 뒤로가기 버튼을 누르거나 목록으로 가는 버튼을 누르면 1페이지로 돌아가게 된다. 이를 해결하기 위해서는 세부 화면으로 넘어가기 전에 페이지를 기억하여 뒤로가거나 목록으로 갈때 저장했던 페이지로 이동해야 한다. 이것을 쉽게 해결해 주는 것이 Svelte Store이다.

 

Store변수의 값을 전역적으로 저장할 수 있음. 따라서  라우팅 되는 페이지에 상관없이 스토어에 저장된 변수를 사용할 수 있다.

 

[store변수 생성: /frontend/src/lib/store.js]

  • 변수를 쓰기모드로 만들어 준다.
// store.js


import {writable} from "svelte/store"

export const page = writable(0)

 

  • 만든 변수를 Home.svelte 에서 사용한다
  • 기존에 정의했던 page변수는 삭제한다.
  • store를 통해 만든 전역변수를 사용하기 위해서는 변수명 앞에 $를 붙여줘야 한다.
import { page } from "../lib/store";


let question_list = []
let size = 10
let total = 0
// let page = 0 // 삭제
$:total_page = Math.ceil(total/size)


  
function get_question_list(_page) {
let params = {
  page: _page,
  size: size
}
fastapi('get', '/api/question/list', params, (json) => {
  question_list = json.question_list
  $page = _page //수정
  total = json.total
})  
}

get_question_list($page) //수정
  
 
 
 //.....생략.....
 
 <ul class="pagination justify-content-center">
    <!-- 이전페이지 -->
    <li class="page-item {$page<=0 && 'disabled'}">
      <button class="page-link" on:click={() => {get_question_list($page-1)}}>이전</button>
    </li>
    <!-- 페이지번호 -->
    {#each Array(total_page) as _, loop_page }
    {#if loop_page >= $page-5 && loop_page <= $page+5}
    <li class="page-item {loop_page === $page && 'active'}">
      <button class="page-link" on:click={() => {get_question_list(loop_page)}}>{loop_page+1}</button>
    </li>      
    {/if}
    {/each}
    <!-- 다음페이지 -->
    <li class="page-item {$page >= total_page-1 && 'disabled'}">
      <button class="page-link" on:click={() => get_question_list($page+1)}>다음</button>
    </li>
  </ul>

 

 

[Persistent Store: 지속성 스토어]

  • store를 활용해 페이지를 저장해도 문제가 있음
  • 원하는 페이지로 이동해 특정 질문의 상세화면으로 들어가 새로고침을 누르고 목록이나 뒤로가기 버튼을 누르면
  • 다시 1페이지로 돌아감(새로고침 되면서 page변수가 0으로 초기화 되었기 때문)
  • 이 문제를 해결하기 위해 스토어에 저장한 변수 값이 항상 유지될 수 있게 지속성을 지닌 스토어가 필요
  • store.js파일을 지속성 스토어로 변경
import {writable} from "svelte/store"


const persist_storage = (key, initValue) => {
	const storageValueStr = localStorage.getItem() //localStorage에 저장된 페이지가 있는지 확인
    // localStorage에 저장된 page가 있으면 그 값을 씀. 없으면 initValue 사용
	const store = writable(storageValueStr != null ? JSON.parse(storageValueStr) : initValue)
    // 새로운 writable값이 들어왔을 때
    store.subscribe((val) => {
    	localStorage.setItem(key, JSON.stringify(val)) //localStorage값 변경
    )
	return store
}

export const page = persist_storage('page', 0)

 

  • 로고는 localStorage에 저장되어 있는 page로 이동하는 것이 아니라 처음 페이지로 돌아가야 함
// /components/Navigation.svelte


<a use:link href="/" on:click={() => {$page=0}}>Pybo</a>

 

  • $page가 변경될때마다 get_question_list()함수도 새로 실행될 수 있도록 반응변수로 변환
$: get_question_list($page) // page가 변할때 마다 get_question_list실행