티스토리 뷰
[React | Issue] 로컬 스토리지가 동기처리라면 API호출 함수에서 문제가 없을까?
blueprint-12 2023. 1. 15. 21:34웹 스토리지?
저장할 데이터가 별로 중요하지 않거나, 유실되어도 무방할 데이터라면 서버 단에서 데이터를 저장하는 것이 낭비일 수도 있습니다. 클라이언트 단, 브라우저 상에 데이터를 저장할 수 있는 기술인 웹 스토리지를 활용해봅시다.
2가지 종류
웹 스토리지에는 크게 localStorage 와 sessionStorage가 있습니다. 두 개의 매커니즘 차이점은 데이터가 어떤 범위 내에서 얼마나 오래 보존되느냐 입니다. 세션 스토리지는 웹 페이지의 세션이 끝날 때 저장된 데이터가 지워지는 반면, 로컬 스토리지는 웹 페이지의 세션이 끝나더라도 데이터가 지워지지 않습니다.
-> 💥브라우저에서 같은 웹 사이트를 여러 탭이나 창을 띄우면, 여러 개의 세션 스토리지에 데이터가 서로 격리되어 저장되며, 각 탭이나 창이 닫힐 때 저장해 둔 데이터도 함께 소멸합니다. 반면, 로컬 스토리지의 경우, 여러 탭이나 창 간에 데이터가 서로 공유되며 탭이나 창을 닫아도 데이터는 브라우저에 남게 됩니다.
웹 스토리지는 DB의 대체품이 아니다.
로컬 스토리지의 데이터 영속성(persistenece)은 어디까지나 계속해서 동일한 컴퓨터에서 동일한 브라우저를 사용할 때만 해당합니다. 즉, 다른 기기나 다른 브라우저 간에 데이터가 공유되고 영속되어야 한다면 당연히 클라우드 플랫폼이나 데이터 베이스 서버를 공유해야 합니다.
엄밀히 말하면 localStorage는 window.localStorage를 사용해야 하지만, 윈도우 객체의 대부분의 속성이 그렇듯 줄여서 localStorage로 로컬 스토리지 객체에 접근이 가능합니다.
주의 사항
웹 스토리지는 오직 문자형 데이터 타입만 지원합니다.
예를 들어 숫자형 데이터를 로컬 스토리지에 쓰고(저장) 다시 읽어보면 본래 숫자가 아닌 문자가 나옵니다.
->웹 스토리지는 문자열 데이터밖에 저장할 수 없기 때문에, 다른 타입의 데이터를 저장하려고 할 때 문자형으로 변환을 합니다.
이에 대한 해결 방법으로 많이 사용하는 방법이 JSON형태로 데이터를 읽고 쓰는 것입니다.
> localStorage.setItem('json', JSON.stringify({a: 1, b: 2}))
// undefined
> JSON.parse(localStorage.getItem('json'))
// {a: 1, b: 2}
위와 같이 로컬 스토리지에 쓸 데이터를 JSON형태로 직렬화(serialization)하고, 읽은 데이터를 JSON 형태로 역직렬화(deserialization)해주면 원본의 데이터를 그대로 얻을 수 있습니다. -> 배열형 데이터도 마찬가지입니다.
localStorge의 모든 작업은 동기로 이루어집니다. 즉, 원하는 것을 바로 실행이 된다는 것입니다. session과 cookie에는 저장만료가 있지만 localStorage에는 저장 만료일이 없습니다. 하나의 도메인 당 5 ~10MB정도로 작은 용량의 데이터를 담을 수 있지만 순수 텍스트로 5MB를 채우는 건 말도 안됩니다.(양이 상당합니다.)
궁금한 점
로컬 스토리지의 모든 작업이 동기로 이루어진다는 것은 localStorage.setItem("") 를 할 때, 해당 코드가 비동기함수 내부에 들어가있으면 안된다는 말로 이해하였는데요. 이 부분에 대해서 자세히 찾아보니 Promise의 후속처리 메서드 then이나 async await 으로 비동기 처리가 끝난 뒤 동기적으로 처리할 수 있는 문법이 존재하여 크게 문제는 없어보입니다.
하지만, 비동기 작업을 처리하는 최신 문법인 async await 문법에서도 async가 promise객체를 반환한다고 되어있습니다. 결국 함수 전체가 비동기 함수가 되는 것인데 그 내부에서 await 으로 동기적으로 비동기 처리를 한다했을 때, 웹스토리지 작업을 하는 코드에 다른 영향은 없는 지 정확히는 잘 모르겠네요.
function 앞에 async를 붙이면 해당 함수는 항상 프라미스를 반환합니다. 프라미스가 아닌 값을 반환하더라도 이행 상태의 프라미스(resolved promise)로 값을 감싸 이행된 프라미스가 반환되도록 합니다. -MDN-
리팩토링을 한다면, api호출에서 token값을 가져와야할 때에는 항상 localStorage.getItem으로 가져올 게 아니라 클라이언트 상태관리 라이브러리(redux, redux toolkit, recoli 등)에서 한 번 저장해두고 api를 호출하는 로직에 토큰 값을 넣어주는 게 좋을 거 같네요. 혹은 context를 생성하거나..?
비동기 함수는 동기 함수 내부에서 사용할 수 없고 비동기 함수를 사용하기 위해서는 해당 함수도 비동기 함수가 되어야 한다는 것을 참고 자료를 통해 배울 수 있었습니다 . 비동기 함수의 전염성이라고 할 수 있겠습니다. multi thread가 아니라면 결국 비동기 함수의 작업을 다시 실행할 때 해당 함수의 call stack 전부를 가져와야 한다고 나와 있습니다. 최근 pc나 모바일 환경은 성능적으로 상향되어있기 때문에 큰 문제가 없다고 보지만 엔진 내부에서 call stack을 찾기 위한 여정을 하고 있다는 점을 기억하라고 당부하는 좋은 내용의 참고 자료이니 읽어보시기 바랍니다.
참고 자료: https://willowryu.github.io/2021-05-21/
ref: https://www.daleseo.com/js-web-storage/
'Frontend > react.js' 카테고리의 다른 글
- Total
- Today
- Yesterday
- grid flex
- 항해99프론트후기
- nvm경로 오류
- 원티드 프리온보딩 프론트엔드 챌린지 3일차
- tilde caret
- && 셸 명령어
- 타입스크립트 DT
- D 플래그
- float 레이아웃
- 부트캠프항해
- 프리렌더링확인법
- 틸드와 캐럿
- Prittier
- 항해99추천비추천
- 원티드 3월 프론트엔드 챌린지
- fs모듈 넥스트
- is()
- aspect-ratio
- 형제 요소 선택자
- 타입스크립트 장점
- 원티드 FE 프리온보딩 챌린지
- 항해99프론트
- nvm 설치순서
- getServerSideProps
- ~ ^
- 프리온보딩 프론트엔드 챌린지 3월
- getStaticPaths
- text input pattern
- 원티드 프리온보딩 FE 챌린지
- reactAPI
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |