state를 만들어서 사용해보면서 새로고침을 하면 항상 데이터들이 리셋이 되었다.
왜냐면 브라우저가 새로고침이 되면서 html,css,js파일들을 다시 읽기 때문이다.
서버에 데이터를 보내서 디비에 데이터를 저장하면 이를 방지할 수 있는데 내가 현재 서버나 DB가 없다면 localStorage를 사용해보자.
크롬개발자 도구에서 Application 탭에 들어가면 로컬스토리지가 보일 것이다.
참고 밑에있는 Sesssion Storage도 똑같은데 다만 브라우저를 끄면 다 삭제된다.
localStorage.setItem('데이터이름', '데이터'); 저장
localStorage.getItem('데이터이름'); 가져오기
localStorage.removeItem('데이터이름'); 삭제
localStorage.clear(); // 전부 다 삭제
로컬스토리지는 문자만 저장할 수 있다고 했다.
그래서 array/object를 저장할 수 없다.
하지만 JSON을 사용한다면 저장이 가능하다.
localStorage.setItem('obj', JSON.stringify({name:'kim'}) );
JSON.stringify() 라는 함수에 array/object를 집어넣으면 그 자리에 JSON으로 반환된 걸 남겨준다.
그러면 "{"name":"kim"}" 이렇게 저장이된다.
당연히 꺼내올 때도 JSON 형태로 꺼내오게 된다
JSON -> array/object로 변환하고 싶으면 JSON.parse(JSON데이터)를 해주면 된다.
App.js
useEffect( () =>{
if(!localStorage.getItem('watched')){
localStorage.setItem('watched', JSON.stringify([]));
}
},[])
먼저 페이지가 렌더링 되었을 때, 로컬스토리지에 watched라는 키를 가진 배열을 저장해두었다.
위에 if문은 app.js가 다시 재렌더링 되었을 때, 배열이 사라지고 또 다시 새로운 배열을 만드는 것을 방지하기 위해 작성했다.
Detail.js
useEffect(() =>{
let watchedItem = new Set(JSON.parse(localStorage.getItem('watched')));
watchedItem.add(findItem.id);
// Set을 배열로 변환 후 다시 저장
localStorage.setItem('watched', JSON.stringify(Array.from(watchedItem)));
},[]);
앞서서 나는 findItem라는 데이터를 출력하기 위해 props로 받아와서, 해당 아이템의 id와 url파라미터로 받아온 id와 같은지 체크하고 그에 맞는 아이템을 가져오도록 하였다.
그래서 그 코드를 재활용해서 사용했다.
처음에는
// let watchedItem = JSON.parse(localStorage.getItem('watched'));
// watchedItem.push(findItem.id);
// localStorage.setItem('watched', JSON.stringify(watchedItem));
이렇게 작성했는데
여기서 자꾸 1이 저장이 되는 것이었다.
왜 그런지 살펴보니
push는 배열 끝에 요소를 추가하고, 배열의 길이를 반환해준다.
그런걸 생각하지도 않고 사용하고 있어서 골머리를 앓았다.
뭐 이렇게 만들어졌다.
UI 꾸미는 건 귀찮아서 이렇게 해놨다.
나중에 해봐야지