상태를 이해하기 위해서 일단 공식문서 'React로 사고하기' 읽기
- Store : 상태가 관리되는 단 하나의 공간! (컴포넌트와 별개이다.) 아래는 createStore 메소드를 활용해 reducer를 연결하는 방법이다.
import { createStore } from "redux"; const store = createStore(rootReducer);
- Action : Store에게 운반할 데이터, 어떤 액션을 취할 것인지 정의한 자바스크립트 객체이다. type은 필수로 지정해 주고, 그 외의 것들은 선택적으로 사용한다.
export const addToCart = (itemId) => { return { type: ADD_TO_CART, payload: { quantity: 1, itemId } } } export const removeFromCart = (itemId) => { // ... } // ...이렇게 액션들을 모아놓는다.
- Reducer: 현재 상태와 Action을 이용해 다음(새로운) 상태를 만들어 내는 pure function이다. Reducer 함수를 작성할 때 주의해야 할 점은 state 업데이트는 immutable한 방식으로 변경해야 한다는 것이다.(
Object.assign()
를 이용!)
아래는 쇼핑몰의 장바구니 액션에 대한 reducer이다.const itemReducer = (state = initialState, action) => { switch (action.type) { // action에서 필수적으로 써 준 type으로 분기 case ADD_TO_CART: return Object.assign({}, state, { cartItems: [...state.cartItems, action.payload] }); break; case REMOVE_FROM_CART: return Object.assign({}, state, { cartItems: [...state.cartItems].filter(el => el.itemId !== action.payload.itemId) }); break; default: return state; } }
- Single source of truth : 동일한 데이터는 항상 같은 곳(
Store
)에서 데이터를 받아온다.- State is read-only : React에서
setState
로 상태를 변경했듯이 Redux는Action
으로만 상태를 변경할 수 있다- Changes are made with pure functions : 순수 함수인
Reducer
를 통해 이전 상태와 Action을 받아 다음 상태를 반환한다.*다음 순서를 기억할 것
Action
객체 ->Dispatch
전달 ->Reducer
호출 ->New State
!
Presentational 컴포넌트 : 화면(UI)를 표현하는 부분 ex. App.js
Container 컴포넌트 : 데이터를 다루는 부분 ex. 그 외 Component...
- useSelector: 컴포넌트와 state를 연결하는 역할을 한다. 컴포넌트에서 useSelector 메소드를 통해 store의 state에 접근할 수 있다.
- useDispatch: Action을 전달하는 메소드로, dispatch로 Reducer를 호출해 state의 값을 바꾸는 역할을 한다. 예를 들어, Action 이 일어날만한 곳은 클릭 등의 이벤트가 일어나는 컴포넌트이다.
아래는 위의 쇼핑몰 장바구니 액션을 활용한 예시이다.import React from 'react'; import { useSelector, useDispatch } from 'react-redux'; function ItemListContainer() { const state = useSelector(state => state.itemReducer); // 위에서 만든 Reducer함수와 연결 const dispatch = useDispatch(); const handleClick = (item) => { dispatch(addToCart(item)) // 이런 식으로 아이템을 담아 리듀서를 호출한다. } return ( <> // ... <Item item={item} key={idx} handleClick={() => {handleClick(item)}} /> </> ) }
자세한 건 공식문서 'react-redux'를 참고하자!