상세 컨텐츠

본문 제목

[리액트] Redux 3 : store의 state 변경하는 법

리액트

by front-hyun 2023. 9. 23. 01:21

본문

store의 state 변경하는 법 

 

큰 그림부터 그려드리면 

state 수정해주는 함수부터 store.js에 만들어두고

그걸 컴포넌트에서 원할 때 실행하는 식으로 코드를 짭니다. 

버튼누르면 예전에 'kim' 이라고 저장해놓은걸 'john kim' 으로 수정하고 싶으면 어떻게 해야할지 알아봅시다. 

정확한 step으로 딱딱 알려드려야 혼자 코드짤 때 편하니까 step을 알려드리면 

 

1. store.js 안에 state 수정해주는 함수부터 만듭니다. 

let user = createSlice({
  name : 'user',
  initialState : 'kim',
  reducers : {
    changeName(state){
      return 'john ' + state
    }
  }
}) 

slice 안에 reducers : { } 열고 거기 안에 함수 만들면 됩니다.

- 함수 작명 맘대로 합니다.

- 파라미터 하나 작명하면 그건 기존 state가 됩니다.

- return 우측에 새로운 state 입력하면 그걸로 기존 state를 갈아치워줍니다. 

 

이제 changeName() 쓸 때 마다 'kim' -> 'john kim' 이렇게 변할듯 

 

 

함수 여러 개 만들기 가능

 

 

2. 다른 곳에서 쓰기좋게 export 해둡니다.

export let { changeName } = user.actions 

이런 코드 store.js 밑에 추가하면 됩니다.

slice이름.actions 라고 적으면 state 변경함수가 전부 그 자리에 출력됩니다.

그걸 변수에 저장했다가 export 하라는 뜻일 뿐임 

 

이렇게 함수를 { } 안에 계속 적으면 export가 되는 것임.

 

 

 

3. 원할 때 import 해서 사용합니다. 근데 dispatch() 로 감싸서 써야함 

 

예를 들어서 Cart.js 에서 버튼같은거 하나 만들고

그 버튼 누르면 state를 'kim' -> 'john kim' 이렇게 변경하고 싶으면

 

(Cart.js)

import { useDispatch, useSelector } from "react-redux"
import { changeName } from "./../store.js"

  let dispatch = useDispatch();


(생략) 

<button onClick={()=>{
  dispatch(changeName())
}}>버튼임</button>

이렇게 코드짜면 됩니다. 

- store.js에서 원하는 state변경함수 가져오면 되고 

- useDispatch 라는 것도 라이브러리에서 가져옵니다.

- 그리고 dispatch( state변경함수() ) 이렇게 감싸서 실행하면 state 진짜로 변경됩니다. 

 

진짜인지 궁금하면 user라는 state 한 번 출력해보십시오.

dispatch로 꼭 감싸야 실행됩니다.

 

+ 버튼 클릭하면 johnkim으로 바뀌는 것을 볼 수 있다.

 

import { Table } from "react-bootstrap";
import { useSelector, useDispatch } from "react-redux";
import { changeName } from "./../store";
function Cart() {
  let state = useSelector((state) => state);
  let dispatch = useDispatch();
  console.log(state.cart);
  return (
    <div>
      {state.user}의 장바구니
      <Table>
        <thead>
          <tr>
            <th>#</th>
            <th>상품명</th>
            <th>수량</th>
            <th>변경하기</th>
          </tr>
        </thead>
        <tbody>
          {/*cart 내에 있는 array 자료만큼 반복해라! cart는 [{}, {}] 구조*/}
          {state.cart.map((a, i) => (
            <tr key={i}>
              <td>{a.id}</td>
              <td>{a.name}</td>
              <td>{a.count}</td>
              <td>
                <button
                  onClick={() => {
                    dispatch(changeName());
                  }}
                >
                  +
                </button>
              </td>
            </tr>
          ))}
        </tbody>
      </Table>
    </div>
  );
}

export default Cart;

 

 

정리!!

 

그지같고 복잡한데요

 

store안에 있는 state를 수정하고 싶으면 

- state 수정해주는 함수를 store.js에 만들어두고 

- 컴포넌트는 그걸 부르기만 하는 식으로 state 수정하게 되어있습니다. 

 

 

Q. 왜 이렇게 복잡하고 그지같나요?

Redux 만든 사람이 정한 문법일 뿐이라 Redux 만든사람에게 뭐라하면 됩니다. 

 

 

Q. 컴포넌트에서 state 직접 수정하면 편하지 않나요?

그럼 당장은 편한데 나중에 프로젝트가 커지면 심각한 단점이 있을 수 있습니다. 

 

 

 

컴포넌트 100개에서 직접 'kim' 이라는 state 변경하다가

갑자기 'kim'이 123이 되어버리는 버그가 발생하면

범인 찾으려고 컴포넌트 100개를 다 뒤져야합니다. 

 

 

 

 

 

근데 state 수정함수를 store.js에 미리 만들어두고

컴포넌트는 그거 실행해달라고 부탁만 하는 식으로 코드를 짜놓으면

'kim'이 123이 되어버리는 버그가 발생했을 때 범인찾기가 수월합니다.

범인은 무조건 store.js에 있으니까요. (수정함수를 잘 만들어놨다면)

 

 

 

아무튼 그런 장점 덕분에 저렇게 코드를 짜는 것일 뿐이고

예습 차원으로

Cart 페이지에 만들어둔 버튼누르면 왼쪽에 있는 수량이 +1 되는 기능을 만들어봅시다.

 

 

관련글 더보기