ToDo List 만들기 (Redux)

😎·2022년 12월 6일
0

PROJECT

목록 보기
3/26

완성한 프로젝트 화면

깃헙 주소 https://github.com/kkookk55/ToDoList-using-Redux-

리덕스를 이용한 TO DO LIST 만들기!

이번 주차엔 Redux를 이용하여 todolist를 만들어 보았는데용 : )

리덕스를 사용하는데 흐름과 개념이해에 많은 시간을 쏟았던거 같습니다 !

사전적인 개념이 아닌 제가 이해한 개념으로 나열 하자면

  • redux 폴더는 redux와 관련된 모든 코드들을 모아놓을 폴더
  • cofig 폴더는 redux의 설정과 관련된 파일을 모아놓을 폴더
  • configsotre는 중앙관리소? 데이터저장하는 설정코드파일
  • modules 폴더는 우리가만들 state들의 그룹을 저장하는 폴더

위와 같이 폴더를 잡아놓고 프로젝트를 진행 했습니다.

이번 프로젝트에선 저번과 달리 nanoid 패키지를 이용하여 고유한 id 값을 만드는데 이용 하였습니다!

Works.jsx

// src/pages/Works.js

import ToDoList from "../component/ToDoList";
import React, { useState } from "react";
import { Link, useParams } from "react-router-dom";
import { useSelector } from "react-redux";
import { useDispatch } from "react-redux/es/exports";
import { insertToDo } from "../redux/modules/toDo";
import { nanoid } from "nanoid";
import DoneList from "../component/DoneList";

const Works = () => {
  const dispatch = useDispatch();
  const [title, setTitle] = useState("");
  const [text, setText] = useState("");

  const toDo = {
    id: nanoid(),
    title: title,
    text: text,
    isDone: false,
  };
  const toDoStore = useSelector((state) => state.toDo);
  return (
    <div>
      <div style={style}>
        <h1> MY TO DO LIST </h1>
        <label>제목</label>
        <input
          style={inputStyle}
          type="text"
          name="title"
          onChange={(e) => {
            setTitle(e.target.value);
          }}
          value={title}
          required
        />
        <label>내용</label>
        <input
          style={inputStyle}
          type="text"
          name="text"
          onChange={(e) => {
            setText(e.target.value);
          }}
          value={text}
          required
        />
        <button
          style={btnStyle}
          onClick={() => {
            dispatch(insertToDo(toDo));
            setText("");
            setTitle("");
          }}
        >
          추가하기
        </button>
      </div>
      <hr />
      <ToDoList></ToDoList>
      <hr />
      <DoneList />
    </div>
  );
};

export default Works;

text 와 title은 useState를 이용하였고 버튼이 클릭되면 그값을 빈문자열로 초기화 시켜 줍니다 !

ToDoList.js

import React, { useState, useCallback } from "react";
import { Link, useParams } from "react-router-dom";
import { useSelector } from "react-redux";
import { useDispatch } from "react-redux/es/exports";
import toDo from "../redux/modules/toDo";
import { render } from "@testing-library/react";
import { itIsDone, deleteToDo } from "../redux/modules/toDo";

function ToDoList() {
  const toDoStore = useSelector((state) => state.toDo);
  const dispatch = useDispatch();

  return (
    <div>
      <h2> Working....!!!!</h2>
      <div style={divStyle}>
        {toDoStore.map((item) => {
          if (item.isDone === false) {
            return (
              <div key={item.id} style={listStyle}>
                <Link to={`/work/${item.id}`} style={linkStyle}>
                  <h3>{item.title}</h3>
                  <p style={pStyle}>{item.text}</p>
                </Link>

                <button
                  style={btnStyle}
                  onClick={() => {
                    dispatch(deleteToDo(item.id));
                  }}
                >
                  삭제하기
                </button>
                <button
                  style={btnStyle}
                  onClick={() => {
                    dispatch(itIsDone(item.id));
                  }}
                >
                  완료하기
                </button>
              </div>
            );
          }
        })}
      </div>
    </div>
  );
}

export default ToDoList;

추가한 리스트들을 보여주는 컴포넌트 입니다

Wokr.jsx

// src/pages/Work.js

import React from "react";
import { useParams } from "react-router-dom";
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";

function Work() {
  const toDoStore = useSelector((state) => state.toDo);
  const param = useParams();
  const work = toDoStore.find((item) => item.id === parseInt(param.id));
  return (
    <div style={divStyle}>
      {toDoStore.map((item) => {
        if (item.id === param.id) {
          return (
            <div>
              <h1>{item.title}</h1>
              <p style={pStyle}>{item.text}</p>
              <Link to={`/works`}>돌아가기</Link>
            </div>
          );
        }
      })}
    </div>
  );
}

export default Work;

리스트 상세보기 페이지입니다.
useParams를 이용하여 id값으로 넘어온 값과 같은 id값을 가진 데이터를 찾아 보여줍니다 !

modules/toDo.js

// src/modules/toDo.js

const INSERT_TODO = "INSERT_TODO";
const ITIS_DONE = "ITIS_DONE";
const DELETE_TODO = "DELETE_TODO";
export const insertToDo = (payload) => {
  return {
    type: INSERT_TODO,
    payload: payload,
  };
};
export const itIsDone = (payload) => {
  return {
    type: ITIS_DONE,
    payload: payload,
  };
};

export const deleteToDo = (payload) => {
  return {
    type: DELETE_TODO,
    payload: payload,
  };
};
// 초기 상태값
const initialState = [];

// 리듀서
const toDo = (state = initialState, action) => {
  switch (action.type) {
    case DELETE_TODO:
      return state.filter((item) => {
        if (item.id === action.payload) {
          return;
        } else {
          return item;
        }
      });
    case INSERT_TODO:
      return [...state, action.payload];
    case ITIS_DONE:
      return state.filter((item) => {
        if (item.id === action.payload) {
          item.isDone = !item.isDone;
          return item;
        } else {
          return item;
        }
      });

    default:
      return state;
  }
};

export default toDo;

리듀서와 액션을 설정한 파일입니다
프로젝트를 진행하면서 알게된 부분으로
리듀서가 리턴으로 '반환하는 값'이 state로 재정의 됩니다.

shared/Router.js

import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "../pages/Home";
import Layout from "./Layout";
import Work from "../pages/Work";
import Works from "../pages/Works";

const Router = () => {
  return (
    <BrowserRouter>
      <Layout>
        <Routes>
          <Route path="/" element={<Works />} />
          <Route path="works" element={<Works />} />
          <Route path="work/:id" element={<Work />} />
        </Routes>
      </Layout>
    </BrowserRouter>
  );
};

export default Router;

App.js

import "./App.css";
import Router from "./shared/Router";

function App() {
  return <Router />;
}

export default App;
profile
개발 블로그

0개의 댓글