완성한 프로젝트 화면
깃헙 주소 https://github.com/kkookk55/ToDoList-using-Redux-
이번 주차엔 Redux를 이용하여 todolist를 만들어 보았는데용 : )
리덕스를 사용하는데 흐름과 개념이해에 많은 시간을 쏟았던거 같습니다 !
사전적인 개념이 아닌 제가 이해한 개념으로 나열 하자면
위와 같이 폴더를 잡아놓고 프로젝트를 진행 했습니다.
이번 프로젝트에선 저번과 달리 nanoid 패키지를 이용하여 고유한 id 값을 만드는데 이용 하였습니다!
// 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를 이용하였고 버튼이 클릭되면 그값을 빈문자열로 초기화 시켜 줍니다 !
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;
추가한 리스트들을 보여주는 컴포넌트 입니다
// 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값을 가진 데이터를 찾아 보여줍니다 !
// 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로 재정의 됩니다.
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;
import "./App.css";
import Router from "./shared/Router";
function App() {
return <Router />;
}
export default App;