티스토리 뷰

728x90

2020/11/30 - [React] - [React] 12. 리덕스(Redux) 개념 정리하기

2020/12/04 - [React] - [React] 13. 리덕스(Redux) 사용해서 카운터 만들기

 

이번에는 앞에서 공부한 리덕스를 사용하여 투두 리스트를 만들어 볼 예정입니다.

리액트 리덕스를 적용한 투두 리스트 만들기 01

 

프로젝트 생성 및 라이브러리 설치

새로운 프로젝트를 먼저 생성하여 줍니다.

npx create-react-app todolist-app 

 

생성된 프로젝트에 사용할 라이브러리들(redux, styled-component, react-icons등)을 설치하여 줍니다.

저는 투두 리스트를 꾸며주기 위해 styled-component를 사용하였습니다.

npm install redux
npm install react-redux
npm install styled-components
npm install react-icons

 

스토어 생성

Todo

src>reducer>Todo.js

 

저는 Todo.js 안에 액션과 액션 생성 함수, 리듀서를 만들어 주었습니다.

 

먼저, 사용할 액션의 타입을 정의하여 주세요!

저는 아래와 같이 4가지의 액션 타입을 사용하였습니다. 각각 추가/제거/수정/토글을 의미합니다.

/* 액선 정의 */
const TODO_INSERT = "TODO/INSERT";
const TODO_REMOVE = "TODO/REMOVE";
const TODO_UPDATE = "TODO/UPDATE";
const TODO_TOGGLE = "TODO/TOGGLE";

 

그리고 액션 생성 함수를 정의하여 주세요! 각각의 액션 생성 함수는 컴포넌트에서 받아온 인자를 전달받아 사용합니다.

/* 액션 생성 함수 */
export const todoInsert = (id, text) => {
  return {
    type: TODO_INSERT,
    payload: {
      id: id,
      text: text,
      isCompleted: false,
    },
  };
};
export const todoRemove = (id) => {
  return {
    type: TODO_REMOVE,
    payload: { id: id },
  };
};
export const todoUpdate = (id, text) => {
  return {
    type: TODO_UPDATE,
    payload: { id: id, text: text },
  };
};
export const todoToggle = (id) => {
  return {
    type: TODO_TOGGLE,
    payload: { id: id },
  };
};

 



초기 상태도 만들어줍니다.

const initState = {
  todos: [
    {
      id: 1,
      text: "TODOLIST 만들기",
      isCompleted: false,
    },
  ],
};

 

마지막으로 리듀서(Reducer)를 만들어줄 거예요!

저는 state의 기본 값으로 위에서 생성해준 initState를 설정해주었고, 비구조 할당을 사용하여 {type, payload}를 받아올 것입니다.

/* 리듀서 생성 */
export default function todoReducer(state = initState, { type, payload }) {
  switch (type) {
    case TODO_INSERT:
      return {
        ...state,
        todos: state.todos.concat({
          id: payload.id,
          text: payload.text,
          isCompleted: false,
        }),
      };
    case TODO_REMOVE:
      return {
        ...state,
        todos: state.todos.filter((todo) => todo.id !== payload.id),
      };
    case TODO_UPDATE:
      return {
        ...state,
        todos: state.todos.map((todo) =>
          todo.id === payload.id ? { ...todo, text: payload.text } : todo
        ),
      };
    case TODO_TOGGLE:
      return {
        ...state,
        todos: state.todos.map((todo) =>
          todo.id === payload.id
            ? { ...todo, isCompleted: !todo.isCompleted }
            : todo
        ),
      };
    default:
      return { ...state };
  }
}

 

 

Todo.js 전체 코드

더보기
/* 액선 정의 */
const TODO_INSERT = "TODO/INSERT";
const TODO_REMOVE = "TODO/REMOVE";
const TODO_UPDATE = "TODO/UPDATE";
const TODO_TOGGLE = "TODO/TOGGLE";


/* 액션 생성 함수 */
export const todoInsert = (id, text) => {
  return {
    type: TODO_INSERT,
    payload: {
      id: id,
      text: text,
      isCompleted: false,
    },
  };
};
export const todoRemove = (id) => {
  return {
    type: TODO_REMOVE,
    payload: { id: id },
  };
};
export const todoUpdate = (id, text) => {
  return {
    type: TODO_UPDATE,
    payload: { id: id, text: text },
  };
};
export const todoToggle = (id) => {
  return {
    type: TODO_TOGGLE,
    payload: { id: id },
  };
};

const initState = {
  todos: [
    {
      id: 1,
      text: "TODOLIST 만들기",
      isCompleted: false,
    },
  ],
};

/* 리듀서 생성 */
export default function todoReducer(state = initState, { type, payload }) {
  switch (type) {
    case TODO_INSERT:
      return {
        ...state,
        todos: state.todos.concat({
          id: payload.id,
          text: payload.text,
          isCompleted: false,
        }),
      };
    case TODO_REMOVE:
      return {
        ...state,
        todos: state.todos.filter((todo) => todo.id !== payload.id),
      };
    case TODO_UPDATE:
      return {
        ...state,
        todos: state.todos.map((todo) =>
          todo.id === payload.id ? { ...todo, text: payload.text } : todo
        ),
      };
    case TODO_TOGGLE:
      return {
        ...state,
        todos: state.todos.map((todo) =>
          todo.id === payload.id
            ? { ...todo, isCompleted: !todo.isCompleted }
            : todo
        ),
      };
    default:
      return { ...state };
  }
}

 

src>index.js

 

이제 store를 사용하기 위해 아래와 같이 작업해주세요!

store변수에는 createStore를 사용하여 todoReducer에서 반환된 상태값을 담아줍니다. 그리고 Provider를 사용하여 하위 컴포넌트들도 store에 접근이 가능하게 만들어 줍니다.

const store = createStore(todoReducer);
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

 

이렇게 store를 완성하였는데요! 다음 시간에는 컴포넌트를 만들어 스토어를 적용해보도록 하겠습니다!

728x90
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크