일전에 사이드프로젝트를 진행하면서 로컬스토리지와 세션스토리지 그리고 쿠키를 이용했었고
지금도 회사업무를 진행하면서 세션과 로컬스토리지, 쿠키를 이용하고있습니다.
하지만.... 사이드프로젝트를 진행할 당시 뭔가... 뭔가가 부족했었는데...
요즘이야 백, 프론트 상관없이 올포지션을 다 다룰수 있어야하지만... 난 아직도 부족하기 때문에
백엔드 프로젝트를 혼자서 구현하기가 아직도 버거워요. 그러다가 문득 찾은 것이 indexedDB!!!
이름 그대로 DB이다! mdn web docs 에서는 이렇게 설명하고 있습니다.
IndexedDB는 파일이나 블롭 등 많은 양의 구조화된 데이터를 클라이언트에 저장하기 위한 로우 레벨 API입니다. IndexedDB API는 인덱스를 사용해 데이터를 고성능으로 탐색할 수 있습니다.
라고 설명하고 있습니다! 조금 더 자세한 설명은 아래의 링크로 접속하시면 볼 수 있습니다!
https://developer.mozilla.org/ko/docs/Web/API/IndexedDB_API
IndexedDB API - Web API | MDN
IndexedDB는 파일이나 블롭 등 많은 양의 구조화된 데이터를 클라이언트에 저장하기 위한 로우 레벨 API입니다. IndexedDB API는 인덱스를 사용해 데이터를 고성능으로 탐색할 수 있습니다. Web Storage는
developer.mozilla.org
1. React에 indexedDB 살짝 끼얹어보기
이제 진짜로 indexedDB를 React 프로젝트에 적용시켜보겠습니다.
일단 프로젝트의 root 파일에 indexedDB를 열어준다고(?) 작성을 해줍니다.
MDN 문서에서는 아래와 같이 나와있습니다.
// In the following line, you should include the prefixes of implementations you want to test.
window.indexedDB =
window.indexedDB ||
window.mozIndexedDB ||
window.webkitIndexedDB ||
window.msIndexedDB;
// DON'T use "var indexedDB = ..." if you're not in a function.
// Moreover, you may need references to some window.IDB* objects:
window.IDBTransaction =
window.IDBTransaction ||
window.webkitIDBTransaction ||
window.msIDBTransaction;
window.IDBKeyRange =
window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
// (Mozilla has never prefixed these objects, so we don't need window.mozIDB*)
다만 TypeScript를 사용하면 window.indexedDB 만 인식되고 있었습니다.
저는 작성할 때 root 파일에 indexedDB를 초기화 하고 필요한 객체 저장소를 생성하는 함수를 실행시키게 설정해놨습니다.
export const indexedDBStart = () => {
const indexedDB = window.indexedDB;
const dbName = "tableName";
const request = indexedDB.open(dbName, 1);
request.onupgradeneeded = (e: any) => {
const db = e.target.result;
const articleStore = db.createObjectStore("article", {
keyPath: "id",
autoIncrement: true,
});
const memberStore = db.createObjectStore("member", {
keyPath: "id",
autoIncrement: true,
});
};
request.onsuccess = (e: any) => {
console.log("성공");
};
request.onerror = (e: any) => {
console.error("실패 : ", e.target.error);
};
};
indexedDBStart 가 실행되면 dbName 이라는 이름의 DB, 그리고 버전은 1인 indexedDB 를 열어달라고 요청합니다. 그리고 만약 해당 indexedDB가 없으면 dbName, 버전 1 이라는 indexedDB를 생성하게 됩니다.
request.onupgradeneeded 를 통해 데이터베이스 객체를 가져온 후 article 과 member 란 객체 저장소를 생성하게 됩니다.
그리고 객체 저장소 생성에 성공하면 console.log에 '성공' 이라는 메시지가 출력되고
만약 실패한다면 '실패 : error' 가 출력됩니다.
자 이제 개발자모드를 켜서 확인해보시면 아래와 같이 브라우저 저장소가 생성되어있습니다!
2. indexedDB에 데이터 저장해보기
이제 저장소를 만들었으니 해당 저장소에 post 하는 방법을 알아보겠습니다.
먼저 article 에 게시글을 저장해보겠습니다.
export const indexedDBPost = (postDatas: any) => {
const idb = window.indexedDB;
return new Promise((resolve, reject) => {
const dbOpen = idb.open("tableName", 1);
dbOpen.onsuccess = () => {
const db = dbOpen.result;
const transaction = db.transaction("article", "readwrite");
const tableNameDB = transaction.objectStore("article");
const postData = tableNameDB.put({
title: postDatas.title,
contents: postDatas.contents,
createDt: postDatas.createDt,
writer: postDatas.writer,
});
postData.onsuccess = (e) => {
transaction.oncomplete = () => {
db.close();
};
resolve(e.type);
};
postData.onerror = (e) => {
console.error("error : ", e);
reject(e);
};
transaction.oncomplete = () => {
db.close();
};
};
});
};
해당 함수를 통해 글 작성 버튼을 누르면 아래의 캡처화면과 같이 indexedDB에 게시글 정보가 저장됩니다.
해당 캡쳐에서는 샘플용으로 간단하게 작성해서 데이터를 작성했지만 실제로는 쿠키나 스토리지보다 더 많은 데이터를 저장시킬 수 있습니다.
해당 캡쳐는 제가 사이드프로젝트를 하면서 indexedDB를 활용하여 작성 한 데이터 샘플입니다. 캡쳐본처럼 다양한 데이터를 저장시킬 수 있는 장점이 있습니다.
3. indexedDB에 저장된 데이터 불러오기
그럼 간단하게 데이터를 저장해봤는데 이번에는 저장된 데이터를 불러오는 방법을 알아보겠습니다!
export const getAllDataFromIndexedDB = () => {
const idb = window.indexedDB;
return new Promise((resolve, reject) => {
const dbOpen = idb.open("tableName", 1);
dbOpen.onsuccess = () => {
let db = dbOpen.result;
const transaction = db.transaction("article", "readonly");
const reviewDB = transaction.objectStore("article");
const review = reviewDB.getAll();
review.onsuccess = (e: any) => {
const data = e.srcElement.result;
console.log('성공 데이터 불러오기',data);
resolve(data);
};
review.onerror = (e) => {
console.log("error", e);
reject(e);
};
transaction.oncomplete = () => {
db.close();
};
};
});
};
indexedDB에 저장된 데이터를 불러오는 코드입니다. 기본적은 구조는 post와 비슷합니다.
먼저 오픈 할 테이블을 선택해준 후 dbOpen 이 성공하면 해당 db안의 컬럼을 선택해주고 컬럼안의 데이터들을 불러와주면 끝입니다.
정상적으로 console에 찍히는 모습을 볼 수 있습니다.
만약 저장된 데이터가 여러개라면 아래의 캡쳐와 같이 console에 찍히게 됩니다!
이제 컴포넌트에서 불러온 데이터를 state애 저장 후 사용하면 됩니다!
만약 특정한 값의 데이터만 불러오고 싶은 경우가 있는데 저는 filter를 통해 특정 데이터를 선택한 후 resolve에 넣어주어 사용하고 있습니다.
// 특정 데이터 선별해서 사용하기
export const getAllDataFromIndexedDB = (postWriter:string) => {
const idb = window.indexedDB;
return new Promise((resolve, reject) => {
const dbOpen = idb.open("tableName", 1);
dbOpen.onsuccess = () => {
let db = dbOpen.result;
const transaction = db.transaction("article", "readonly");
const reviewDB = transaction.objectStore("article");
const review = reviewDB.getAll();
review.onsuccess = (e: any) => {
const data = e.srcElement.result;
const filterData = data.filter((item) => item.writer === postWriter)
console.log('필터 불러오기',filterData);
resolve(filterData);
};
review.onerror = (e) => {
console.log("error", e);
reject(e);
};
transaction.oncomplete = () => {
db.close();
};
};
});
};
4. indexedDB에 저장된 데이터 삭제하기
삭제또한 매우 간단합니다. indexedDB에 저장 시 자동으로 생성되는 id값으로 데이터 삭제를 진행합니다.
export const indexedDBDelete = (id: number) => {
const idb = window.indexedDB;
return new Promise((resolve, reject) => {
const dbOpen = idb.open("tableName", 1);
dbOpen.onsuccess = () => {
const db = dbOpen.result;
const transaction = db.transaction("article", "readwrite");
const tableNameDB = transaction.objectStore("article");
const deleteRequest = tableNameDB.delete(id);
deleteRequest.onsuccess = () => {
transaction.oncomplete = () => {
db.close();
resolve(true);
};
};
deleteRequest.onerror = (e) => {
console.error("error : ", e);
reject(e);
};
transaction.oncomplete = () => {
db.close();
};
};
});
};
삭제 함수를 통해 삭제를 진행하는데 만약 id =2 인 값을 삭제하면 아래와 같이 해당 id를 가진 컬럼이 삭제됩니다.
이상 간단하게 indexedDB사용법을 정리해봤습니다.
indexedDB를 메인으로 사용하기에는 다방면으로 무리가 있을 듯 하지만 그래도 로컬환경에나서 프론트 기준에서 백엔드 작업이 진행되지 않았을 때에는 필요한 데이터를 최대한 비슷한 환경에서 테스트해보기에는 좋을 것 같습니다.
잘못된 부분 지적은 언제나 감사합니다.
'Programming > JavaScript' 카테고리의 다른 글
[JavaScript] 배열이란?? (0) | 2022.10.22 |
---|---|
[JavaScript]JS의 Number 속성 소수점 제어 (0) | 2022.10.22 |
[JavaScript]Front로 가기위한 나만을 위한 JS 기초다지기-데이터 타입 (0) | 2022.09.02 |
[React]React 프로젝트 git에 배포 시 Link _blank (0) | 2022.08.11 |
[JavaScript]변수에 할당 된 데이터 타입 조회 방법 (0) | 2022.08.09 |