이전에 useState를 이용한 Pagination을 구현했었다. 생각대로 구현은 잘 되었지만, 뒤로가기 했을 때, page의 값이 어딘가에 저장되어 있지 않아 page의 값이 다시 1로 초기돠 되는 일이 생긴것이다.
Final Project를 했을때는 Redux-toolkit의 persistStore와 PURGE를 사용하여 LocalStorage에 접근하여 state값을 유지했었는데 이번에는 Redux를 사용하지 않다보니 직접적으로 LocalStorage를 사용해야했었다.
먼저 내가 저장해야할 상태값은 명확하게 Page였다. 이 값을 기억하고 있어야 Pagination의 값을 정할 수 있었으며 currPage 또한 값을 변경할 수 있었기 때문이다.
하여 먼저 LocalStorage에 접근하여 저장할 수 있는 방법을 찾았다.
const [page, setPage] = useState(
() => JSON.parse(window.localStorage.getItem("count")) || 1
);
웹 스토리지는 오직 문자형 데이터 타입만 지원하기 때문에 숫자를 넣는다고 해도 문자가 나오게 된다. 웹 스토리지는 문자열 데이터 밖에 저장할 수 없기 때문에 다른 타입의 데이터를 저장하려고 할 때 문자형으로 변환을 하기 때문이다. 이러한 웹 스토리지의 성질로 인해 객체형 데이터를 저장할 때 오류가 생길 수 있다.
웹 스토리지를 사용할 때 위와 같은 문제를 피하기 위해서는 JSON 형태로 데이터를 읽고 쓰는 방식이 필요하다.
이후 useEffect를 사용해서 컴포넌트의 상태 값을 웹 스토리지에 저장할 수 있게 해준다.
useEffect(() => {
window.localStorage.setItem("page",JSON.stringify(page));
}, [page]);
page의 값이 변경될 때마다 로컬 스토리지에서 바뀌는 값이 저장될 수 있도록 useEffect를 사용했다.
헌데 Pagination.js에서도 page값이 바뀌어 저장되는 것처럼 currPage도 바뀌어 로컬 스토리지에 저장되어 page가 5개가 잘 유지될 수 있도록 해야했다.
결국 똑같은걸 2번써야한다니..차라리 이걸 캡슐화(?) 커스텀 훅스를 만들어 사용하면 좋을것 같아 따로 파일을 만들었다.
Hooks.js
import { useState, useEffect } from "react";
function LocalStorage(key, initialState) {
const [state, setState] = useState(
() => JSON.parse(window.localStorage.getItem(key)) || initialState
);
useEffect(() => {
window.localStorage.setItem(key, JSON.stringify(state));
}, [key, state]);
return [state, setState];
}
export default LocalStorage;
그냥..위의 2개를 합쳐 LocalStorage 함수를 불러 사용하면 중복코드를 줄일 수 있을것 같았다.
하여 이 파일을 이용해 Pagination.js와 MainPage의 page, currPage의 값을 바뀔 수 있도록 하였다.
MainPage.js
const [page, setPage] = LocalStorage("page", 1);
Pagination.js
const [currPage, setCurrPage] = LocalStorage("currPage", page)
let firstNum = currPage - (currPage % 5) + 1
let lastNum = currPage - (currPage % 5) + 5
간단하게 useState를 사용했던 부분에 LocalStorage로 바꾸어 주어 사용할 이름과 값을 넣어 간편하게 바꿀 수 있었다.
Paginatio.js
import React from "react"
import LocalStorage from "../../Hooks"
import {
PageSection, ButtonWrap,
Button
} from './styled'
function Pagination ({page, totalPosts, limit, setPage}){
const numPages = Math.ceil(totalPosts/limit)
const [currPage, setCurrPage] = useLocalStorage("currPage", page)
let firstNum = currPage - (currPage % 5) + 1
let lastNum = currPage - (currPage % 5) + 5
//console.log({"currPage is":currPage, "firsNum is" : firstNum, "page is" : page})
return (
<PageSection>
<ButtonWrap>
<Button
onClick={() => {setPage(page-1); setCurrPage(page-2);}}
disabled={page===1}>
<
</Button>
<Button
onClick={() => setPage(firstNum)}
aria-current={page === firstNum ? "page" : null}>
{firstNum}
</Button>
{
Array(3).fill().map((_, i) =>{
return (
<Button
border="true"
key={i+1}
onClick={() => {setPage(firstNum+1+i)}}
aria-current={page === firstNum+1+i ? "page" : null}>
{firstNum+1+i}
</Button>
)
})}
{
<Button
border="true"
key ={lastNum+1}
onClick={() => setPage(lastNum)}
aria-current={page === lastNum ? "page" : null}>
{lastNum}
</Button>
}
<Button
onClick={() => {setPage(page+1); setCurrPage(page);}}
disabled={page===numPages}>
>
</Button>
</ButtonWrap>
</PageSection>
)
}
export default Pagination;