728x90

Overview

Redux 는 기본적으로 액션 - 리듀서 - 스토어 - 상태 로 이루어져 있다고 이해하고 있다.
추가적으로 구독이나 디스패치, 미들웨어 등이 있다.
중요한 개념은 스토어에 등록된 리듀서에서 디스패치된 액션 타입 별로 상태를 변화 시켜 주는것으로 이해된다.

나는 Redux 디렉토리를 만들고 그 안에 Redux를 사용하는 프로젝트 별로 액션과 리듀서를 작성하고,
CombineReducers를 index.js에 선언에 RootReducer를 Export하는 방식으로 사용할 계획을 가지고 시작한다.

1. 디렉토리 및 파일 만들기


src 디렉토리에 Redux 를 디렉토리를 만들고, 그안에 TodoList 디렉토리를 만들어 준다.
각각 index.js 파일을 만들어 준다.

 

그리고 webpack.config.js 에 resolve alias에 @Redux를 추가해 주었다.

  resolve: {
    extensions: [".js", ".json", ".wasm"],
    alias: {
      "@pages": path.resolve(__dirname, "src", "pages"),
      "@resources": path.resolve(__dirname, "src", "resources"),
      "@components": path.resolve(__dirname, "src", "components"),
      "@project": path.resolve(__dirname, "src", "project"),
      "@Redux": path.resolve(__dirname, "src", "Redux"),
    },
  },

 

2. 액션과 액션 함수

 

이번 TodoList 에서는 액션-> 리듀서 순으로 작성하고, 필요한 기능들을 그때그때 추가 하는 식으로 진행을 해볼까한다.

액션은 상태 변화가 필요할때 사용되는 객체이다. 

type을 필수적으로 가지고 있어야한다.

액션함수는 이러한 액션을 만들어 주는 함수이며, 파라미터로 받는 값들을 액션 객체에 담아 줄수 있다.

가장 기본적인 CRUD 기능을 액션으로 만들어 줍니다.

각 액션 type에 들어갈 문자열을 변수에 담아 액션 함수를 만들어 줍니다.

const CREATE = "todolist/ADD";
const READ = "todolist/READ";
const UPDATE = "todolist/UPDATE";
const DELETE = "todolist/DELETE";

export const onCreate = () => {
  return {
    type: CREATE,
  };
};
export const onRead = () => {
  return {
    type: READ,
  };
};
export const onUpdate = () => {
  return {
    type: UPDATE,
  };
};
export const onDelete = () => {
  return {
    type: DELETE,
  };
};

 

 액션함수명 앞에는 on을 붙여 줍니다.

각 액션함수를 export 합니다.

 

3. 리듀서

리듀서는 상태와 액션을 파라미터로 받아 액션 타입에 맞는 변화가 일어나고, 새로운 상태값을 리턴해 줍니다.

Store에등록된 상태로 컴포넌트에서 발생한 dispatch+액션으로 상태를 변화시킵니다.

export const TodoListReducer = (state = [], action) => {
  switch (action.type) {
    case CREATE:
      console.log("CREATE");
      return state;
    case READ:
      console.log("READ");
      return state;
    case UPDATE:
      console.log("UPDATE");
      return state;
    case DELETE:
      console.log("DELETE");
      return state;
    default:
      return state;
  }
};

우선 switch 문을 통해 case에 해당하는 액션이 들어왔을때 실행하는 함수를 정의해 주는 형태로 사용됩니다. 하지만, 아직 아무런 기능에 대한 정의가 없으므로 console만 찍어 줍니다.

 

export!

 

3. CombineReducers & RootReducers

스토어는 1개만 가능 합니다.

정의된 상태나 리듀서가 많을 경우에는 CombineReducers 를 통해 하나의 Reducer로 만든후 store에 등록합니다.

import { combineReducers } from "redux";
import { TodoListReducer } from "@Redux/TodoList";

const rootReducer = combineReducers({
  TodoListReducer,
});

export default rootReducer;

위에서 만든 TodoListReducer를 넣어 rootReducer를 만들어 주고, export 합니다.

 

4. CreateStore

이제 이렇게 만든 Reducer를 createStore를 통해 store로 만들어 반영합니다.

// index.js
// modules
import React from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import ReactDOM from "react-dom";
import { legacy_createStore as createStore } from "redux";
import { Provider } from "react-redux";

// components
import App from "./src/App";
import rootReducer from "@Redux";


const store = createStore(rootReducer);

const rootDomElement = document.getElementById("App");
const rootRenderElement = createRoot(rootDomElement);
const rootJsxElement = (
  <BrowserRouter>
    <Provider store={store}>
      <App />
    </Provider>
  </BrowserRouter>
);

// Rendering

if (rootDomElement.hasChildNodes()) {
  ReactDOM.hydrate(rootJsxElement, rootDomElement);
} else {
  rootRenderElement.render(rootJsxElement);
}

redux에서 제공하는 createStore에 rootReducers를 넣어 store를 생성한뒤 Provider 컴포넌트의 props로 넣어주고, Provider를 App 컴포넌트의 상위에 위치 시켰습니다.

 

이제 정의되 액션을 디스패치하여 상태 변화를 일으켜 보도록하는 과정을 진행하면 될것같습니다.

728x90

+ Recent posts