• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 React 게시판 로컬 스토리지 장바구니 추가

로컬 스토리지 장바구니 추가

7 글 보임 - 1 에서 7 까지 (총 7 중에서)
  • 글쓴이
  • #47650

    김지우
    참가자
    localstorage 로 쉽게 기능을 잘 만든 줄 알았는데 앱을 몇 번 더 사용해 보면서 이상한 점을 발견했습니다.
    혼자 기능 만들기란 정말 쉽지 않은 것 같습니다...ㅠㅠ
    
    아래 store.js 에 state 변경시 local storage에도 업데이트 하는 기능을 넣었습니다. 
    사실 이 두줄을 추가한게 답니다.
    localStorage.removeItem('cartState'); 
    localStorage.setItem('cartState', JSON.stringify(state))
    
    let cart = createSlice({ 
    name : 'cart',
    initialState : [],
    reducers : {
    addItem(state, action) {
    let found = state.findIndex((a)=>{return a.id === action.payload})
    if (found >= 1){
     state[found].quan++;
     } else {
     state.push(action.payload);
     }
     localStorage.removeItem('cartState');
     localStorage.setItem('cartState', JSON.stringify(state))
     },
    addCount(state, action) {
    let found = state.findIndex((a)=>{return a.id === action.payload})
     state[found].quan++;
     localStorage.removeItem('cartState');
     localStorage.setItem('cartState', JSON.stringify(state))
     },
    subCount(state, action) {
    let found = state.findIndex((a)=>{return a.id === action.payload})
    if (state[found].quan > 1) {
     state[found].quan--;
     } else if (state[found].quan <= 1) {
    delete(state[found]);
     state = state.filter((a,i) => a != null); //delete 한 뒤 남는 null값 제거
     }
     localStorage.removeItem('cartState');
     localStorage.setItem('cartState', JSON.stringify(state))
     }
     }
    });
    
    이후 장바구니에 상품 1개를 추가한 뒤 홈페이지 버튼을 누르면 로컬스토리지에 잘 남습니다.
    그런데 홈버튼(localhost:3000 으로 이동하는 버튼)을 누른 후 
    장바구니 추가 버튼을 누르면 로컬스토리지는 상품을 추가하지 않고 누른 상품 하나로 갈아치워집니다.
    
    즉 1번 상품 추가 => 홈 버튼 => 2번 상품 추가를 누르면
    로컬 스토리지에는 [{1번 상품 객체}, {2번 상품 객체}] 가 아닌 [{2번 상품 객체}] 만 남습니다.
    
    그런데 정말 이상한 점은 뒤로가기( 맥북 터치패드 제스처로 뒤로가기) 를 하면 잘 로컬스토리지에 잘 추가가 된다는 점입니다.
    (생각해보니 홈버튼을 눌렀다 오면 상품의 재고가 100에서 99로 되지 않는 문제와 비슷한 것 같지만,
    장바구니에 다시 들어가보면 로컬스토리지에 담긴 상품 1개 까진 잘 추가가 되어 있습니다)
    
    아래는 Detail.js 입니다.
    
    <button
    className = "buttonGreen"
    style={{width:'85px'}}
    onClick={() => {
    찾은상품개수변경(()=>{
     찾은상품.quan --;
     })
    dispatch(
    addItem({_id: 찾은상품._id, id: 찾은상품.id, name: 찾은상품.title, quan: 1})
     );
    navigate("/cart");
     }}
    >
     장바구니
     </button>
    
    아래 cart.js 에서 로컬 스토리지에 있는 'cartState' 를 띄워줬습니다. 어떤 점이 문제일까요? 
    
    let cartState = localStorage.getItem('cartState');
    let cartStateArray = JSON.parse(cartState);
    
    ...
    
     <tbody>
     {
     cartStateArray[0] === null ? null : cartStateArray.map((a,i)=>
    <tr key={i}>
     <td>{}</td>
     <td>{ a.name }</td>
     <td>{ a.quan }</td>
     <td><button className="buttonOrange" role="button" onClick={
     ()=>{dispatch(addCount(a.id))}}>+1</button>
     <button className="buttonGreen" role="button" onClick={
     ()=>{dispatch(subCount(a.id))}}>-1</button>
     </td>
     </tr>
     )
    }
     </tbody>
    
    #47682

    codingapple
    키 마스터
    메인페이지 방문하면 로컬스토리지 초기화하라는 코드가 App 이런데에 있나봅니다
    #47741

    김지우
    참가자
    놀랍게도 <Nav.Brand> 라는 부트스트랩 컴포넌트가 로컬스토리지를 초기화 하고 있었네요.
    <Nav.Link> 로 바꾸니 로컬스토리지가 잘 동작합니다!
    
    그런데 상품 2개를 담아 2개 모두의 개수를 늘린 뒤 2번째 상품 개수를 줄여 없애고
    1번째 상품 개수를 조작할려고 하면
    [{"_id":0,"id":0,"name":"This is my seat","quan":3},null]
    이렇게 없던 null 값이 생기고, 화면은 하얀 빈 화면으로 바뀌며 
    브라우저 콘솔에서 TypeError: null is not an object (evaluating 'a.id') / Cart.js: 29 이런 에러가 뜹니다.
    
    Cart.js 의 29번 째 줄의 a.id는 img src 코드인데 아마도 있던 a.id 가 null 값이 되자 에러가 난 것 같습니다.
    왜 없던 null 값이 갑자기 생겨서 화면이 하얗게 변할까요?
    {
     cartStateArray[0] === null ? null : cartStateArray.map((a,i)=> 
    <tr key={i}>
     <td>{}</td> 
     <td>{ a.name }</td>
     <td>{ a.quan }</td>
     <td><button className="buttonOrange" role="button" onClick={
     ()=>{dispatch(addCount(a.id))}}>+1</button>
     <button className="buttonGreen" role="button" onClick={
     ()=>{dispatch(subCount(a.id))}}>-1</button>
     </td>
     </tr>
     )
    }
    
    제가 store.js 에서 delete 함수를 썼을 때 저렇게 null 값이 남아서
    그 바로 아래에 (윗 댓글에 코드 있습니다)
    delete(state[found]);
    state = state.filter((a,i) => a != null);
    이렇게 제거를 했는데도 불구하고 다시 없던 null 값이 생기고야 맙니다ㅠㅠ
    
    
    #47794

    codingapple
    키 마스터
    addCount 이런거할 때는 해당상품을 못찾았을때 예외처리하는 코드가 없는듯요
    #47885

    김지우
    참가자
    addCount 는 addItem 이 보낸 state, 즉 {_id: 찾은상품._id, id: 찾은상품.id, name: 찾은상품.title, quan: 1}이런 게 있어야만 
    카트에서 버튼을 눌러 쓸 수 있는 거라서 카트에 없을 때는 아예 쓸 수 없지 않나요?
    그래서 예외처리를 어떻게 해야 하는지 우선 잘 이해가 되지 않습니다ㅠㅠ
    아래는 Detail.js 에서의 addItem() 입니다.
    <button
    className = "buttonGreen"
    style={{width:'85px'}}
    onClick={() => {
    dispatch(
    addItem({_id: 찾은상품._id, id: 찾은상품.id, name: 찾은상품.title, quan: 1})
    );
    navigate("/cart");
    console.log(state);
    }}
    >
    장바구니
    </button>
    그리고 이게 delete 함수를 사용하면 홈버튼 눌러서 똑같은 상품이나 다른 상품을 추가해도 
    store.js 의 a.id 가 undefined 라면서 
    TypeError: undefined is not an object (evaluating 'a.id') 라고 뜹니다.
    여기서 delete 를 사용한 것이 에러의 근원일까요?
    
    ------------혼자 얼렁뚱땅 답을 찾았습니다ㅠㅠ -----------
    아아.. delete 가 근원이었습니다..
    state.pop(state[found]); 으로 바꾸니 잘 되네요.
    그리고 말씀하신 예외 처리라는 게 이렇게 해봤는데 맞는 걸까요?
    
    addItem(state, action) {
    let found = state.findIndex((a)=>{return a.id === action.payload})
    if (state[found]){
     state[found].quan++;
     } else {
     state.push(action.payload);
     }
     localStorage.removeItem('cartState');
     localStorage.setItem('cartState', JSON.stringify(state))
     },
    addCount(state, action) {
    let found = state.findIndex((a)=>{return a.id === action.payload});
    if (state[found]){
     state[found].quan++;
     }
     localStorage.removeItem('cartState');
     localStorage.setItem('cartState', JSON.stringify(state))
     },
    subCount(state, action) {
    let found = state.findIndex((a)=>{return a.id === action.payload})
    if (state[found].quan > 1) {
     state[found].quan--;
     } else if (state[found].quan <= 1) {
     state.pop(state[found]);
     }
     localStorage.removeItem('cartState');
     localStorage.setItem('cartState', JSON.stringify(state))
     }
    
    
    #47955

    codingapple
    키 마스터
    if 조건식에는 found > 0 이런것만 써도 될듯요
    #47980

    김지우
    참가자
    그렇군요..! 이번에도 친절한 답변 정말 감사합니다!
7 글 보임 - 1 에서 7 까지 (총 7 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관, 개인정보처리방침
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠