-
localStorageReact 2022. 3. 25. 17:17
사이트를 새로고침/재접속하면 js파일도 처음부터 다시 읽기 때문에 초기화가 된다. 이때, state데이터를 기억하게 하려면 서버로 보내서 DB에 저장하던가 아니면 브라우저 저장공간에 저장을 하면 된다. 즉, DB없이 데이터를 저장하고 싶으면 localStorage를 사용하면 된다.
Storage에는 Local과 Session이 있는데 Session은 새로고침하면 날라가지만 Local은 날라가지 않는다.
localStorage 문법은 3개 정도가 있다.
1. setItem
localStorage.setItem('name','Kim') 이렇게 key가 name 이고 value가 Kim인 자료를 저장할 수 있다.
2. getItem
localStorage.getItem('name') 이렇게 자료의 이름만 입력하면 자료를 출력할 수 있다.
3. removeItem
localStorage.removeItem('name') 이렇게 입력하면 자료를 삭제할 수 있다.
session을 다루려면 local대신 sessionStorage이렇게만 써주면 된다.
Storage는 ""를 친 문자만 저장 가능하다.
하지만,object자료를 저장할 때, 그냥 넣으면 깨지게 된다.
만약 저장하고 싶다면, localStorage.setItem( 'obj', "{"name" : 'kim'}" ) 이렇게 글자처럼 JSON처럼 만들어주면 된다.
매번 다 따옴표를 칠 수 없으니 JSON.stringify({name : 'kim'}) 이렇게 저장해주면 다 따옴표 처리가 된다.
여기서, var a = localStorage.getItem('obj')라고 저장을 하고,
따옴표를 제거하려면 JSON.parse(a)를 쳐서 따옴표를 제거해주면 된다.
localStorage.setItem( 'obj', JSON.stringify({name : 'kim'}) ); var a = localStorage.getItem('obj'); JSON.parse(a) //=>{name : "kim"}
이제 응용해보자.
Detail페이지 방문시 localStorage에 정보저장을 하고, 정보를 보여주는 최근본상품UI를 만들면 끝이다.
정보저장부터 해보자
//Detail컴포넌트 안에 useEffect(()=>{//로드시 watched라는 항목이 있다고 생각하고watched항목을꺼냄 var arr = localStorage.getItem('watched'); arr = JSON.parse(arr); arr.push(id);//[0,1]같은형태 arr = new Set(arr);//중복제거 Set자료형{1,2,3,4}여긴 중복을 허용안함 여기서{[]}이형태 arr = [...arr];//여기서{}벗겨서 []만 남게함 localStorage.setItem('watched', JSON.stringify(arr) ); },[]);
먼저, Detail컴포넌트에 들어갈 때 실행해야 하므로 useEffect에 []를 써줘서 업데이트시에 실행되는걸 막아준다.
안에는, 먼저 arr이란 변수에 watched가 key인 자료값을 추출해 JSON.parse로 따옴표를 없애주고,
arr이란 []형태 어레이에 useparams로 URL사이트에 Detail/1이면 id가 1 Detail/2면 id가 2가 되게끔 해놓은 걸 이용해
arr.push(id)를 해준다.
여기서 중복검사를 하기 위해서 Set자료형을 이용한다. Set자료형은 {1,2,3,4,4,4}를 중복을 허용안해서 {1,2,3,4}만 남게 해준다. 그래서 arr = new Set(arr)을 해줘서 {[중복안되는수]}만 배열에 담기게 하고,
arr = [...arr]을 이용해 괄호를 벗겨서 다시 어레이로 바꿔준다.
그리고, setItem을 이용해 watched라는 키값에 JSON.stringify(arr)을 해서 따옴표를 다 붙여서 value로 담아준다.
여기까지 하면, 처음에 에러가 난다. 배열안에 아무것도 없어서 push를 할 곳이 없다.라는 에런데
배열이 없으면 다른걸 하거나, 아니면 모든 유저에게 강제로 watched라는 자료를 localStorage에 넣을 수 있다.
배열이 없으면 추가하는 방법을 선택해보면,
if (arr == null) { arr = [] } else { arr = JSON.parse(arr);
이렇게 써줘서 arr배열이 null이면 arr = []배열을 만들어줘라 라고 코드를 짜면된다.
여기까지가 정보저장을 하는 단계이다.
이제 화면에 조잡하지만 UI를 만들어서 나타내보자
let [item,item변경] = useState([]); useEffect(()=>{ var a = localStorage.getItem('watched'); if (a == null) { a = [] } else { a = JSON.parse(a) } item변경(a) })
먼저, useState를 이용해 item이란 빈 배열을 만들어주자. 그 다음, 컴포넌트가 처음 나타났을 때 업데이트 될 때, 다 보여줘야하므로 useEffect를 쓰고, []를 안 써서 업데이트시에도 작동되게 해준다.
a라는 변수에 localStorage에서 watched라는 key의 값의 값을 불러온다. 그럼 위에서 저장한 정보가 나온다.
여기서 우리가 아직 상품을 하나도 안봤을수도 있으니까 만약 불러온 값이 null이면 null인 채로 두고,
그게 아니라면 JSON.parse를 이용해서 따옴표를 없애준다.
그 다음, item변경이라는 state변경함수를 이용해서 a를 item배열에 넣어준다.
<div className="watched"> <div className="list">최근 본 상품</div> { item.map((a,i)=>{ return ( <ul className="list-watched" key={i}> <li >{shoes[a].title}</li> <li><img src={"https://codingapple1.github.io/shop/shoes"+ (parseInt(a)+1) +".jpg"} width="100%" /></li> </ul> ) }) } </div>
이렇게 div박스에 map을 이용한 반복문으로 item배열의 수만큼 반복해주고 각각 해당하는 데이터를 넣어주면 된다.
이때 img태그의 src같은 경우는 숫자가 들어가야하므로 JSON.parse로 따옴표를 제거해준 문자 0,1,2를 parseInt를 이용해 숫자로 바꿔줘야 +1을 했을때 숫자의 연산이 된다.
만약, 문자인 경우 01, 11, 21이 된다.
'React' 카테고리의 다른 글
Node+Express 와 React연동하기 (0) 2022.03.28 PWA (0) 2022.03.25 성능잡기 (lazy loading, React devtools, 재렌더링을 막는 memo) (0) 2022.03.25 state 변경함수 사용시 주의점 : async (0) 2022.03.24 리액트에서 자주쓰는 if문 작성패턴 5개 (0) 2022.03.24