react redux 4

바다캔디·2025년 6월 19일

리액트공부

목록 보기
28/39

Redux 4 : state가 object/array일 경우 변경하는 법

store에 저장된 state가 array, object 자료인 경우
state 변경을 좀 쉽게 편리하게 할 수 있음

1. 값을 직접 변경 가능

Immer.js 라이브러리가 Redux 설치하면 딸려서 설치됨
이 라이브러리가, 오브젝트의 값을 직접 변경해도 state 사본을 하나 더 생성해줌.
즉 아래코드처럼 직접수정해도 잘 반영됨

let user = createSlice({
  name : 'user',
  initialState : {name : 'kim', age : 20},
  reducers : {
    changeName(state){
      state.name = 'park'
    }
  }
}) 

수정이 잦은 문자나 숫자부분은 그냥 오브젝트로 만드는게 더 편할듯.

주의 ) return과 같이쓰지 말것.

왜요?
Immer.js는 state의 불변성을 유지하면서도 직접 수정하는 것처럼 코드를 작성할 수 있게 해줌.
내부적으로는 state의 draft 사본을 만들어서 그걸 직접 수정하듯 작성하게 하고, 수정이 끝나면 불변성을 유지한 새 객체로 바꿔줌.
그래서 직접 수정해도 되는 것처럼 보임.

return은 새 객체로 갈아치우는 방식.
즉 return을 쓸거면

changeName(state) {
  return { name: 'park', age: 20 };  // 완전히 새로운 객체를 명시적으로 리턴
}

이렇게 해야함

결론

둘이 같이 섞어쓰면 에러발생. 둘 중 한 방식만 쓰자.

2. 파라미터

수정함수에 값을 담아보낸다.
이후 함수에서 그 값을 가지고 놀 수 있다.

//cart.jsx
<Button onClick={()=>increase(2)}>나이 수정</Button>

//store.jsx
let user = createSlice({
  name : 'user',
  initialState : {name : 'kim', age : 20},
  reducers : {
    increase(state, action){
      state.age += action.payload
    }
  }
}) 

payload : 대충 실어나른다는 뜻으로 만든거같음

action.type 하면 state변경함수 이름이 나오고
action.payload 하면 파라미터가 나옴

3. 오늘의 숙제

1. + 버튼을 누르면 해당 상품의 수량부분이 +1 되는 기능을 만들어옵시다.

각 배열의 오브젝트에 접근필요. id값 활용하면 될듯

//store.jsx
    //map 반복문을 통해 action.payload로 받아온 id값과 일치하는 item을 찾음. 있다면 아이템을 copy, count+1
    userCartCountIncrement(state, action) {
      return state.map((item) =>
        item.id === action.payload ? { ...item, count: item.count + 1 } : item
      );
    },
    userCartCountDecrement(state, action) {
      return state.map((item) =>
        item.id === action.payload ? { ...item, count: item.count - 1 } : item
      );
    },
 //cart.jsx
                {userCart.map(function (a, i) {
            return (
              <tr>
                <td>{a.id}</td>
                <td>{a.name}</td>
                <td>{a.count}</td>
                <td>
                  <Button
                    onClick={() => dispatch(userCartCountIncrement(a.id))}
                  >
                    +
                  </Button>
                  수량변경
                  <Button
                    onClick={() => dispatch(userCartCountDecrement(a.id))}
                  >
                    -
                  </Button>
                </td>
              </tr>
            );
          })}

2. 상세페이지 주문하기 버튼을 누르면 새로운 상품이 state에 추가되는 기능을 만들기.

userCart state 를 store.jsx에서 가져온 뒤 주문하기 버튼을 클릭하면 새로운 오브젝트를 추가하는 방식으로 하면 될듯.
수정함수에서 기존 state복사, 스프레드 함수를 활용하여 맨 뒤에 넣어놓으면 될듯.

    //기존 배열에 오브젝트 추가 함수
    addUserCart(state, action) {
      //해당 아이디를 가지고있는 오브젝트가 있는지 체크
      const existingItem = state.find((item) => item.id === action.payload.id);
      //있다면 그거 카운트만 하나 증가
      if (existingItem) {
        return state.map((item) =>
          item.id === action.payload.id
            ? { ...item, count: item.count + 1 }
            : item
        );
      } else {
        //없다면, 새 오브젝트 추가.
        return [...state, { ...action.payload, count: 1 }];
      }
    },

copilot이 사실상 80프로 이상 했음...
모르는거 깔짝 찾아보다가 답답해서 ai 쓰는거 그만해야 할거같다.
실력이 늘지를 않음.

0개의 댓글