본문 바로가기
개발 Study/React

[React/Redux] Redux 사용법 (1) -State/Action/Reducer/Store

by jiyoon_92 2022. 8. 4.
반응형

redux

Redux란?

상태 관리 라이브러리로 Component별로 props/state를 바꿔주는 복잡한 관계를 redux 하나로 외부에서 state들을 공용으로 관리하여 가져다 쓸 수 있다.

Redux flow


1. State(상태)

State란 React Component 내에서 사용되는 데이터 집합을 말하며 이 상태 정보를 가지고 컴포넌트의 속성을 바꾸거나 어떤 event가 일어났을 경우 상태 값을 변경하여 Component를 변경된 상태로 렌더링할 수 있다. 

이런 State를 변경하는 것이 (Action)이며 Action과 Store를 연결해주는 스토어 관리자가 (Dispatcher)다.

Store는 State를 관리하는 저장소로 State는 다음과 같이 객체 형식으로 사용한다. 객체 내에서 카테고리 별로 관리가 가능하다.

const initialState = {
    Data : {
      groupData : [],
      roomData : [],
      connectInfoData : [], // {room id, user id, leave time, connecting}
    },
    ListState : {
      groupStates : [],
      groupOpenStates : [],
      roomSelectedStates : [],
      unreadMesssageStates : [], // {room id , message count}
    }
};

 


2. Action

Action은 상태 변경을 일으키는 이벤트에 대한 정적 정보다.

Action은 Reducer가 구분할 수 있도록 액션 타입과 데이터를 가진 객체 형식이다. 아래와 같이 reducer에 있는 액션 타입들을 받아와 외부에서도 action을 일으킬 수 있도록 type과 payload(Data)를 받아 새로운 State로 설정할 수 있도록 Action들을 선언한다.

import {LOGIN, LOGOUT} from "./reducers/userReducer";
import {INIT_LIST, SET_GROUP, SET_ROOM, OPEN_GROUP, SELECT_ROOM, PUSH_MESSAGE, READ_MESSAGE, LEAVE_ROOM} from "./reducers/chatReducer";

export const login = user => ({ type: LOGIN, payload: user });
export const logout = user => ({ type: LOGOUT, payload: user });

export const initList = states => ({type: INIT_LIST, payload : states});
export const setGroup = groupData => ({type: SET_GROUP, payload: groupData});
export const setRoom = roomData => ({type: SET_ROOM, payload: roomData});
export const setConnectInfo = connectInfoData => ({type: LEAVE_ROOM, payload: connectInfoData});

export const openGroup = openStates => ({type: OPEN_GROUP, payload: openStates});
export const selectRoom = selectedStates => ({type: SELECT_ROOM, payload: selectedStates});
export const pushMessage = unreadStates => ({type: PUSH_MESSAGE, payload: unreadStates});
export const readMessage = unreadStates => ({type: READ_MESSAGE, payload: unreadStates});

상태는 반드시 Action을 통해서만 바꿀 수 있으며 그 외의 상황에서는 state를 읽는 것만 가능하다.

반응형

3. Reducer

Reducer는 Action이 일으킨 상태 변화를 Action Type에 따라 Data를 받고 이전 State와 비교하여 새로운 State를 내보낸다.

Action Type을 선언할때는 같은 타입의 액션이 있을 수 있으므로 액션 앞에 Reducer명을 붙여주거나 해서 구분한다. Reducer 내에서는 switch문으로 Action 타입에 따라 State를 비교하고 바꿔준다.

export const LOGIN = "USER/LOGIN";
export const LOGOUT = "USER/LOGOUT";

//UserReducer.js

const initialState = {
  User : {
    id : '',
    nickname : '',
  }
};

const userChecker = (state = initialState, action) => {
    switch (action.type) {
      case LOGIN:
        return {
          ...state,
          User : {
            ...state.User,
            id : action.payload.id,
            nickname : action.payload.nickname,
          }
        };
      case LOGOUT:
        return {
            ...state,
            User : {
              id: '',
              nickname: '',  
            }
        };
      default:
        return state;
    }
  };
export default userChecker;

 

Reducer를 여러개 사용하는 경우 RootReducer를 작성하여 외부에서 여러 개의 Reducer를 접근 가능하도록 한다.

import { combineReducers } from "redux";
import userReducer from "./userReducer";
import chatReducer from "./chatReducer";

const rootReducer = combineReducers({
  userReducer, chatReducer
  });
  
export default rootReducer;

 


4. Store

Store는 State들을 관리하는 저장소다.

createStore()함수로 store를 생성하여 외부에서 사용가능하도록 store.js를 작성한다. 이 때, redux-logger를 store에 추가하고 redux-devtools-extension을 import 하면 prevState/Action/nextState를 log로 쉽게 볼 수 있다.

import { legacy_createStore as createStore, applyMiddleware, compose } from "redux";
import rootReducer from "./reducers/rootReducer";
import logger from "redux-logger";
import { composeWithDevTools } from "redux-devtools-extension";

// logger 사용
const enhancer =
  process.env.NODE_ENV === "production"
    ? compose(applyMiddleware())
    : composeWithDevTools(applyMiddleware(logger));
        
const store = createStore(rootReducer, enhancer);
export default store;

createStore시 deprecated 에러가 뜬다면 아래 이전 글을 참조해보자. ㅎㅎ

2022.08.01 - [개발 Study/Node, js, react] - [Error] Redux createStore 에러 처리 (deprecated)

 

[Error] Redux createStore 에러 처리 (deprecated)

이제 좀 Redux를 배워서 써먹어볼까하고 인터넷에 돌아다니는 예제들을 응용하여 작성 중에 Store 생성시 필요한 함수 createStore()가 deprecated 되어 사용할 수 없다고 떴다. 정확하게 말하면 configureSto

chuun92.tistory.com

<Provider store={store}>
  <App />
</Provider>

생성한 Store는 index.js에서 <App/> 태그 외부에 <Provider>태그를 넣고 store에 생성한 store를 넣어주면 Context를 사용할 수 있다.

자 이렇게 State/Action/Reducer/Store는 생성했다.

UseSelector/UseDispatch로 State를 가져다 쓰고, Action을 일으켜 State를 변경할 수 있다.

이를 어떻게 사용하는지 다음 글에서 알아보자.

 

 

반응형

댓글