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파일의 인코딩/디코딩 작업이 필요합니다.
우선 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;