[React] LocalStorage 사용하기

윤후·2022년 8월 4일
0

React

목록 보기
2/18

React에서 LocalStorage 사용하기

이전에 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}>
                    &lt;
                </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}>
                    &gt;
                </Button>
            </ButtonWrap>
        </PageSection>
    )
}

export default Pagination;

웹 스토리지 사용하기 Reference
웹 스토리지란 Reference

profile
궁금한걸 찾아보고 공부해 정리해두는 블로그입니다.

0개의 댓글