Redux(3)

무과장·2023년 7월 16일
1

react

목록 보기
29/30

숙제1 : 수량 +1 기능 만들기

//store.js
let stock  = createSlice({ //useState 역할임
    name : 'stock',
    initialState : 
     [
        {id : 0, name : 'White and Black', count : 2},
        {id : 2, name : 'Grey Yordan', count : 1}
      ],
      reducers:{
        increaseCount(state, action){
          let idNumber = state.findIndex((a)=>{return a.id === action.payload })
          // 여기서 a는 stock에 담긴 배열을 뜻한다. 
          // 배열의 id와 state.stock[i].id가 같으면 그 인덱스 번호를 찾아서 idNumber에 담아준다. 
          // 그 다음 그 idNumber에 해당하는 count를 1씩 올려준다.
          state[idNumber].count++
        }
      }
})
export let{ increaseCount, addItem } = stock.actions
//Cart.js
state.stock.map((a, i)=>
                 <tr>
                    <td>{[i+1]}</td>
                    <td>{state.stock[i].id}</td>
                    <td>{state.stock[i].name}</td>
                    <td>{state.stock[i].count}</td>
{/* +를 클릭하면 수량이 높아지도록 */}
                    <td>
                    <button onClick={()=>{dispatch(increaseCount(state.stock[i].id))}}>+</button>
                    {/* increaseCount(i)로 해도 되지만 만약 정렬하기 같은 걸 해서 위치가 바뀐다면 원하는 곳에 +가 안 될 것이다.*/}
                    {/* 그러므로 id가 바뀔 때마다 plus를 해주라는 의미에서 작성하는 편이 확실하다 */}
                    </td>
                 </tr>

숙제2 : 주문하기 버튼 누르면 state에 새로운 상품 추가

//store.js
let stock  = createSlice({ //useState 역할임
    name : 'stock',
    initialState : 
     [
        {id : 0, name : 'White and Black', count : 2},
        {id : 2, name : 'Grey Yordan', count : 1}
      ],
      reducers:{
        생략
        },
        addItem(state, action){
          state.push(action.payload)
        }
      }
})
export let{ increaseCount, addItem } = stock.actions
//detail.js
{
             찾은상품.title
            }
          </h4>
          <p>{찾은상품.content}</p>
          <p>{찾은상품.price}원</p>
          <button className="btn btn-danger" onClick={()=>dispatch(addItem({id : 찾은상품.id, name : 찾은상품.title, count : 0}))}>주문하기</button>
        </div>

사실 감이 잘 오지 않았다. 버튼을 누르면 어디에 추가가 되어야 하는 거지? 어떻게 추가를 시켜야하지?
방법은 state.stock에 있는 배열에 버튼을 누르면 또 다른 배열이 추가되는 방식으로 하는 것이었다.
배열의 가장 마지막에 추가되게 하는 메서드는 .push()이다.

응용1 : 표의 행마다 삭제 버튼 만들고 누르면 상품 삭제되게 하기

//Cart.js
<button onClick={()=>{dispatch(deleteItem(state.stock[i].id))}}>x</button>
//store.js
let stock  = createSlice({ //useState 역할임
    name : 'stock',
    initialState : 
     [
        {id : 0, name : 'White and Black', count : 2},
        {id : 2, name : 'Grey Yordan', count : 1}
      ],
      reducers:{
        생략,
        deleteItem(state,action){
          let itemIndex = state.findIndex((a) => a.id === action.payload);
          if (itemIndex !== -1) {
            //배열에서 해당 아이템의 인덱스를 찾았는지 확인한는 조건문
            //배열에서 아이템을 찾지 못한 경우 findIndex 메서드는 -1을 반환함.
            state.splice(itemIndex, 1);
          }
        }
      }
})

state.splice(itemIndex, 1)는 배열에서 itemIndex에 해당하는 인덱스의 요소를 제거하는 메서드이다.


여기서 itemIndex는 찾은 아이템의 인덱스를 나타낸다. 1은 제거할 요소의 개수를 나타낸다. 따라서 state.splice(itemIndex, 1)은 배열 state에서 itemIndex에 해당하는 인덱스의 요소를 1개 제거하는 것을 의미한다.


예를 들어, 배열 state가 [1, 2, 3, 4, 5]이고 itemIndex가 2라면, state.splice(itemIndex, 1)을 실행하면 배열 state는 [1, 2, 4, 5]가 된다. 인덱스 2에 해당하는 요소 3이 제거되었다.


즉, state.splice(itemIndex, 1)은 배열에서 특정 인덱스의 요소를 제거하여 배열을 변경하는 작업을 수행한다.

응용2 : 주문하기 버튼을 누를 때 이미 상품이 state 안에 있으면 추가가 아니라 기존 항목 수량증가만 시키기.

//store.js
addItem(state, action){
          let idNumber = state.findIndex((a)=>{return a.id === action.payload.id })
          if(state[idNumber].id === action.payload.id){
            state[idNumber].count++
          }else{
            state.push(action.payload)
          };
        }

처음에는 코드를 이렇게 짰는데 이상하게도 기존 배열에 있던 게 추가가 되면 count가 잘 올라가는데 새로운 걸 담으면 'Cannot read properties of undefined (reading 'id')
TypeError: Cannot read properties of undefined (reading 'id')
at addItem'에러가 뜨는거라.


뭐야... 그 전에는 id 잘만 인식했잖아!! 왜 갑자기 그러는건데!!


아무리 다른 걸 만지고 혼자서 해결해보려 해도 도저히 실마리가 잡히질 않는다... 그래서 이번엔 bing에게 질문해보았다!

헐, 맞다. findIndex는 아이템을 찾지 못한 경우에는 -1을 반환하지!
와 이걸 간과하고 있었다.

addItem(state, action){
          let idNumber = state.findIndex((a)=>{return a.id === action.payload.id })
          if (idNumber !== -1) {
            if (state[idNumber].id === action.payload.id) {
              state[idNumber].count++;
            }
          } else {
            state.push(action.payload);
          }
        }
//만약 일치하는 요소가 있다면(idNumber !== -1), state[idNumber].id === action.payload.id 조건문을 통해 해당 요소의 count 값을 증가시킨다.
//만약 일치하는 요소가 없다면(else), state.push(action.payload)를 사용하여 state 배열에 새로운 아이템을 추가한다.

해결!

profile
느리더라도 꾸준히 확실하게.

0개의 댓글