PDF 뷰어를 만들면서, 선택된 파일을 상태로 관리하였습니다.

하지만 하이라이트 기능을 구현한 후 클라이언트에서 기억하기 위해서는

궁극적으로 웹 스토리지 사용을 해야하지 않을까? 라는 생각에

해당 내용을 local Storage에 저장해보려 했습니다.

기존 변수에 할당한 pdf 파일은 별도의 인코딩/디코딩 처리를 할 필요 없이 내부적으로 사용가능했습니다.

간략히 써보면 아래와 같습니다.

import { useState } from "react";
import { Document, Page, pdfjs } from "react-pdf";

import "react-pdf/dist/Page/TextLayer.css";
import "react-pdf/dist/Page/AnnotationLayer.css";

pdfjs.GlobalWorkerOptions.workerSrc = "//cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js";

function FileViewer() {
	const [pdfFile, setpdfFile] = useState(null);
	const handleFileChange = (ev) => {
    const pdfFile = ev.target.files[0];

    setpdfFile(pdfFile);
  };
	
	return (
		<input type="file" onChange={handleFileChange} />
		{pdfFile && <Document file={pdfFile}></Document>}
	);
}

useState 로 바로 파일을 업데이트하고 Document에 전달합니다.

만약 컴포넌트를 분리한다면 상태를 올려서 같은 방식으로 사용하거나 전역상태로 관리할 수 있습니다.

하지만 만약 해당 전역상태를 웹스토리지에 저장하고 싶다면 이대로 괜찮을까요?

당연히 안됩니당.

웹스토리지는 기본적으로 stiringify된 JSON 데이터를 취급합니다.

pdf파일의 인코딩/디코딩 작업이 필요합니다.

| web storage 에 저장되는 파일 형식 |

우선 zustand를 사용하여 아래와 같이 전역상태를 생성하였습니다.

import { create } from "zustand";
import { persist, createJSONStorage, devtools } from "zustand/middleware";

const pdfFileStore = persist(
  (set) => ({
    pdfFile: null,
    setFileToStore: (file) =>
      set(() => ({
        pdfFile: file,
      })),
    deleteFileFromStore: () =>
      set(() => ({
        pdfFile: null,
      })),
  }),
  {
    name: "pdfFile-storage",
    storage: createJSONStorage(() => localStorage)
  }
);

const usePdfFileStore = create(devtools(pdfFileStore));

export default usePdfFileStore;