[React] 리덕스로 Counter, ToDoList 구현 (1)

sue·2021년 1월 21일
0

react note

목록 보기
13/17

사전 준비

1) 프로젝트 생성
$ npx create-react-app learn-redux

2) redux 라이브러리 설치
$ cd learn-redux
$ yarn add redux

리덕스 모듈 만들기

리덕스 모듈이란 다음 항목들이 모두 들어있는 자바스크립트 파일을 의미한다.

  • 액션 타입
  • 액션 생성함수
  • 리듀서

리덕스를 사용하기 위해 필요한 위 항목들은 각각 다른 파일에 저장할 수도 있다. 다만 코드들이 서로 다른 디렉토리와 파일에 분리되어 있으면 개발을 하는데 불편하기 때문에, 이번에는 리듀서와 액션 관련 코드들을 하나의 파일에 몰아서 작성한다.
=> Ducks 패턴

counter 모듈 만들기

src 디렉토리 -> modules 디렉토리 -> counter.js 파일 생성

// COUNTER 모듈

// 액션 타입 선언
// 다른 모듈과 중복되지 않기 위해 접두사 붙임
const SET_DIFF = "counter/SET_DIFF";
const INCREASE = "counter/INCREASE";
const DECREASE = "counter/DECREASE";

// 액션생성함수 만들기
// export로 내보냄
export const setDiff = (diff) => ({
  type: SET_DIFF, diff
});

export const increase = () =>{
  type:INCREASE, 
}

export const decrease = () =>{
  type:DECREASE, 
}


// 초기상태 선언
const initialState = {
  number: 0,
  diff: 1
}

// REDUCER 만들기 (STATE 초기값 설정, ACTION 받아와서 상태 변화)
// export default로 내보냄
export default function counter(state = initialState, action){
  switch(action.type){
    case SET_DIFF
    : return {
      ...state,
      diff: action.diff 
    },

    case INCREASE
    : return {
      ...state,
      state: state.number + state.diff
    }
    case DECREASE
    : return {
      ...state,
      state: state.number - state.diff
    }
    default: state
  }

}

todos 모듈 만들기

// 액션 타입 선언
const ADD_TODO = "todos/ADD_TODO"; // 항목 추가
const TOGGLE_TODO = "todos/TOGGLE_TODO"; // 항목 토글

// 액션 생성함수 만들기
// nextId: todo 데이터에서 사용할 고유 id
let nextId = 1;


export const addTodo = (text) => ({// 새 항목 추가
  type: ADD_TODO,
  todo: {
    id: nextId++,
    text,
  }, // todo 객체에 id, text
});

export const ToggleTodo = (id) => ({
  type: TOGGLE_TODO,
  id,
});
// 아이디를 가지고 done값 변경

// 초기 상태 선언 : 빈배열
const initialState = [];
/*
{
    id: 1,
    text: "예시",
    done: false
}
*/

// reducer 만들기
export default function todos(state = initialState, action) {
  switch (action.type) {
    case ADD_TODO:
      return state.concat(action.todo);

    case TOGGLE_TODO:
      return state.map((todo) =>
        todo.id === action.id ? { ...todo, done: !state.done } : todo
      );

    default:
      return state;
  }
}
  • 덕스 패턴 규칙
    - 연관된 액션 타입, 액션 생성자 함수, 리듀서 함수를 하나의 파일로 작성
    - 리듀서 함수는 export default 키워드로 내보냄
    - 액션 생성자 함수는 export 키워드로 내보냄
    - 액션 타입은 접두사와 액션 이름을 조합해서 작명

  • export default와 export 차이
    https://ko.javascript.info/import-export#ref-4122

루트 리듀서 만들기

한 프로젝트에 여러개의 리듀서가 있을때는 이를 한 리듀서로 합쳐서 사용한다. 리듀서를 합치는 작업은 리덕스에 내장된 combineReducers라는 함수를 이용한다.

import { combineReducers } from "redux";
import counter from "./counter";
import todos from "./todos";

const rootReducer = combineReducers({
  counter,
  todos,
});

export default rootReducer;

스토어 만들기

리액트 프로젝트에 리덕스 적용하기
$ yarn add react-redux

src 디렉토리 index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { Provider } from "react-redux";
import { createStore } from "redux";
import rootReducer from "./modules";
import { composeWithDevTools } from "redux-devtools-extension";

const store = createStore(rootReducer, composeWithDevTools());
// console.log(store.getState());

ReactDOM.render(
  <React.StrictMode>
  // Provider컴포넌트 불러와서 App컴포넌트 감싸고, props로 store를 넣어준다. 
    <Provider store={store}> 
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

Provider로 store를 넣어서 App 을 감싸게 되면 렌더링하는 그 어떤 컴포넌트던지 리덕스 스토어에 접근 할 수 있게 된다.

0개의 댓글