오늘은 뭘 해볼거냐면
JSON.stringify와 JSON.parse에 대해서 간단히 알아보고,
localStorage 에 최근 본 상품의 id를 배열로 담아보는 기능을 만들어보겠슴다
JSON.stringify 와
JSON.parse
여기 한 객체가 있습니다
let obj = {name: 'kim'}
만약 이 상태로 localStorage.setItem('data', obj) 해버린다면 예쁜 {name: 'kim'} 요 상태로 저장이 되지 않고,
localStorage의 value에 [object Object] 라며 객체가 깨져서 나올겁니다
<JSON.stringify>
깨져서 안나오고 이쁜 상태로 obj를 보존하려면 어떻게 해야할까?
JSON.stringify로 obj를 감싸면 됩니다!
<JSON.parse>
그렇다면 반대로 JSON 형식을 기존 객체 형태로 바꿔주어야 할때도 있습니다
그냥 JSON 형식을 출력한다면 {"name":"kim"} 이런식으로 key에 ""이 달려있게됩니다
let 꺼낸것 = localStorage.getItem('data')
JSON.parse(꺼낸것), 꺼낸 것을 JSON.parse로 감싸줍니다
콘솔에 찍으면 {name: 'kim'} 라고 기존 객체로 나오게 됩니다
localStorage 에 최근 본 상품의 id를 배열로 담아보는 기능
화면이 렌더링 된 이후에도 상품 id가 바뀔때마다 실행이 되는
useEffect를 써보면 됩니다
일단 의사코드를 순서대로 적어봅시다
1. Detail.js 를 누르면
2. useEffect 코드가 실행되도록
3. 찾은 상품을 선언해준다
4. useEffect 코드에서 찾은상품.id 가 변경될때마다 localStorage 에 새롭게 요소가 추가됨
function Detail(props){
let {id} = useParams(); // id라는 변수에 url파라미터를 남겨줌
// app.js 파일에서 <Route path ="/detail/:id" element ={<Detail shoes={shoes}/>}/>
let 찾은상품 = props.shoes.find((x)=> x.id == id);
//현재 url에 입력한 번호와 같은 번호를 가진 상품을 찾아서 보내줌
console.log(props.shoes)
console.log(찾은상품)
console.log(id)//헷갈려서 찍어봄
useEffect(()=>{
//이전에 저장된 localStorage의 watched 배열을 가져옵니다
let Watched = JSON.parse(localStorage.getItem('watched') || '[]')
//localStorage에서 'Watched'배열을 가져와서 파싱하여 할당하거나,
// 만약 localStorage 이 없다면 Watched는 빈배열을 기본값으로 사용합니다
//새로운 요소를 추가합니다
Watched.push(찾은상품.id)
//업데이트된 watched 배열을 저장합니다. 저장은 맨 마지막에
localStorage.setItem('watched', JSON.stringify(Watched))
},[찾은상품.id])
}
처음에는 Watched를 빈배열로만 선언하니, 문제점이 생겼다
useEffect 가 실행될때마다 계속 Watched 빈배열로 초기화되는 것이다 ;;;
그래서 || 논리 연산자를 사용하여, localStorage.getItem('watched') 가 있다면 그걸 Watched 초기값으로 데려오고 파싱,
만약 없다면 빈배열은 ''로 감싸 JSON 형태로 가져온다음 파싱하도록 짯다
/*
|| 연산자는 논리 연산자 중 하나로, 좌항이 falsy한 값이라면 우항을 반환하고, 그렇지 않은 경우 좌항을 반환합니다. 여기서 falsy한 값이란, false, 0, null, undefined, NaN, ''(빈 문자열) 등의 값을 의미합니다.
따라서, 위 코드에서는 localStorage.getItem('watched')의 값이 falsy한 경우, []이 할당됩니다. 그렇지 않은 경우에는 localStorage.getItem('watched')에서 반환된 값을 JSON.parse() 메소드를 사용하여 파싱하여 할당합니다.
위 코드는, localStorage에서 가져온 watched 배열이 있는 경우 그 값을 사용하고, 없는 경우에는 빈 배열을 사용한다는 의도로 작성된 것입니다.
*/
업데이트된 watched 배열을 localStorage.setItem 로 저장한다. 저장은 맨 마지막에!!
useEffect(()=>{
//생략
},[찾은상품.id])
그리고 의존성 배열 자리에 [찾은상품.id] 넣어주어서
바뀔때마다 useEffect 코드가 실행되도록 한다!!
url 파라미터(id)가 바뀔때마다 다른 상품을 가져오고, 그 상품 id가 localStorage에 저장됨!
+
중복제거하기
만약 같은 상품 페이지에 여러번 접속하면 어떻게 될까요? 상품 id가 중복적으로 누적됩니다.
그럼 '이미 상품 id가 있으면 추가하지말아주세요~' 라고 코드를 짜야 하는데
if를 쓰기 귀찮으니 Set 자료형을 써볼게요
Set은 array 와 똑같은데 중복을 알아서 제거해주는 array 입니다
array <-> Set 변환도 쉬워서
array -> Set-> array 이런식으로 쓰면 중복제거를 좀 쉽게 할 수 있슴다
useEffect(()=>{
//이전에 저장된 localStorage의 watched 배열을 가져옵니다
let Watched = JSON.parse(localStorage.getItem('watched') || '[]')
//localStorage에서 'Watched'배열을 가져와서 파싱하여 할당하거나,
// 만약 localStorage 이 없다면 Watched는 빈배열을 기본값으로 사용합니다
//새로운 요소를 추가합니다
Watched.push(찾은상품.id)
//중복된 값을 제거하기 위해 Set 객체를 활용합니다
const uniqueWatched = Array.from(new Set(Watched))
//업데이트된 watched 배열을 저장합니다. 저장은 맨 마지막에
localStorage.setItem('watched', JSON.stringify(uniqueWatched))
},[찾은상품.id])
'React' 카테고리의 다른 글
React Custom Component 만들기 (모달, 토글, 탭) (0) | 2023.04.19 |
---|---|
Styled Components 문법 총정리 (0) | 2023.04.18 |
Redux-toolkit : 장바구니 기능 관련 응용문제 (0) | 2023.04.13 |
Redux-toolkit : state가 object/array 일 경우 변경하는 법 (0) | 2023.04.09 |
Redux-toolkit : store의 state 변경하는 법 (2) | 2023.04.09 |