일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 부트캠프 #개발일지 #TIL #CSS속성 #float #clear
- 부트캠프 #스파르타코딩클럽 #개발일지# #TIL #Javascript #confirm #location.href
- appendChild
- ㅜㄹㄹ
- 부트캠프 #CSS #개발일지 #TIL
- useState
- 개발일지 #TIL #프론트엔드 #HTML
- useEffect
- Til
- textContent
- 결합선택자
- 부트캠프 #스파르타코딩클럽 #개발일지# #html
- 개발일지
- 알고리즘
- querySelector
- 부트캠프 #개발일지 #TIL #FlexboxFroggy #displayflex #flexbox
- 템플릿스트링
- 부트캠프 #개발일지 #TIL #Position #위치
- 부트캠프 #CSS #개발일지 #TIL #박스모델
- JS예제
- 특성선택자
- React
- 부트캠프 #개발일지 #TIL #그리드 #CSS
- 부트캠프
- 의사클래스
- 깃허브오류
- 리액트
- 부트캠프 #코딩 #개발일지 #프론트엔드 #CSS #TIL
- CSS
- js
- Today
- Total
나의 개발일지
[React] Redux로 TodoList 만들기 본문
<module>
todos.js
import uuid from "react-uuid";
const initialState = [
{
id: uuid(),
title: "리액트",
content: "이해하기",
isDone: false,
},
{
id: uuid(),
title: "리덕스",
content: "사용하기",
isDone: false,
},
{
id: uuid(),
title: "열심히",
content: "공부하기",
isDone: true,
},
];
// action items
const ADD_TODO = "ADD_TODO";
const DELETE_TODO = "DELETE_TODO";
const SWITCH_TODO = "SWITCH_TODO";
// action creator
// action은 객체, type과 payload를 가지고 있다
export const addTodo = (payload) => {
return {
type: ADD_TODO,
payload,
};
};
export const deleteTodo = (payload) => {
return {
type: DELETE_TODO,
payload,
};
};
export const switchTodo = (payload) => {
return {
type: SWITCH_TODO,
payload,
};
};
const todos = (state = initialState, action) => {
switch (action.type) {
case ADD_TODO:
return [...state, action.payload];
case DELETE_TODO:
return state.filter((item) => item.id !== action.payload);
case SWITCH_TODO:
return state.map((item) => {
if (item.id === action.payload) {
return { ...item, isDone: !item.isDone };
} else {
return item;
}
});
default:
return state;
}
};
export default todos;
action items
휴먼 에러를 방지하기 위해 문자를 변수 선언 해준다
action creator
type과 payload를 가지고 있다. payload는 type에 따라 얼만큼 바뀌어야 하는지를 나타낸다
reducer
함수이다. switch문으로 case에 따라 각 다른 type을 가지고 있다
Home.jsx
import React from "react";
import Input from "../component/Input";
import TodoList from "../component/TodoList";
import Footer from "../component/Footer";
const Home = () => {
return (
<div>
<Input />
<TodoList isActive={true} />
<TodoList isActive={false} />
<Footer />
</div>
);
};
export default Home;
isActive 에 불리언 타입으로 false 또는 true를 주어서
TodoList의 삼항연산자를 사용할 때 쓴다
Input.jsx
export default function Input() {
const [title, setTitle] = useState("");
const [content, setContent] = useState("");
const dispatch = useDispatch();
const onHandler = (e) => {
e.preventDefault();
const newTodo = {
id: uuid(),
title,
content,
isDone: false,
};
dispatch(addTodo(newTodo));
};
const onTitleChangeHandler = (e) => {
setTitle(e.target.value);
};
const onContentChangeHandler = (e) => {
setContent(e.target.value);
};
return (
<InputContainer>
<form onSubmit={onHandler}>
<InputTitleBox>
제목 :
<input
type="text"
value={title}
onChange={onTitleChangeHandler}
></input>
</InputTitleBox>
<InputContentBox>
내용 :
<input
type="text"
value={content}
onChange={onContentChangeHandler}
></input>
<button type="submit">추가</button>
</InputContentBox>
</form>
</InputContainer>
);
}
addTodo 리듀서 사용!
함수 안에서 실행되어야 한다!!!
왜 강조하냐고..? 나도 알고 싶진 않았다...
무한 로딩에 빠지게 된다...
input 창에 글을 쓸 때마다 렌더링이 될 것이다
const newTodo = {
id: uuid(),
title,
content,
isDone: false,
};
새로운 변수를 선언하고 객체로 할당해준다
input 창에 글을 쓰면 저 객체의 형식으로 값이 들어간다
isDone이 false이므로 입력값은 해야할 일에 들어간다
TodoList.jsx
export default function TodoList({ isActive }) {
// store에 있는 todos를 가지고 온다
// state 는 store에 있는 모든 모듈을 가져오기 때문에
// 해당되는 모듈만 들고와야 한다 state.todos
const todos = useSelector((state) => state.todos);
// console.log(todos);
const dispatch = useDispatch();
const navigate = useNavigate();
const ondeleteClick = (id) => {
dispatch(deleteTodo(id));
};
const HandelSwitchBtn = (id) => {
dispatch(switchTodo(id));
};
return (
<StyledListBox>
<h4>{isActive ? "해야할 일💥" : "완료된 일💡"}</h4>
{todos
.filter((data) => data.isDone === !isActive)
.map((item) => {
return (
<>
<StyledTodoBox key={item.id}>
<h4>{item.title}</h4>
<div>{item.content}</div>
<button onClick={() => HandelSwitchBtn(item.id)}>
{isActive ? "완료" : "취소"}
</button>
<button onClick={() => ondeleteClick(item.id)}>삭제</button>
<br />
<button
onClick={() => {
navigate(`/${item.id}`);
}}
>
상세보기
</button>
</StyledTodoBox>
</>
);
})}
</StyledListBox>
);
}
const StyledListBox = styled.div`
background-color: lightblue;
padding: 20px;
`;
const StyledTodoBox = styled.div`
background-color: lightgray;
padding: 20px;
margin: 10px;
`;
isActive :
Home으로부터 import를 받아 props를 해준다
{isActive ? "해야할 일💥" : "완료된 일💡"}
true일 땐 해야할 일 list로 , false일 땐 완료된 일 list로 나눠진다
Detail.jsx
const Detail = () => {
const navigate = useNavigate();
const paramId = useParams().id;
const todos = useSelector((state) => state.todos);
const filteredTodo = todos.filter((item) => item.id === paramId)[0];
return (
<StDetailBox>
<div>Detail</div>
<h2 styled={{ marginBottom: "10px" }}>상세페이지</h2>
<br />
제목 : {filteredTodo.title}
<br />
내용 : {filteredTodo.content}
<br />
<button
onClick={() => {
navigate("/");
}}
>
이전 페이지 이동
</button>
</StDetailBox>
);
};
export default Detail;
useParams는 파마미터 값을 URL을 통해서 넘겨받은 페이지에서 사용할 수있도록 하는 Hook이다
해당 id값의 페이지로 넘어가게 해준다
const filteredTodo = todos.filter((item) => item.id === paramId)[0];
paramId와 todos의 id 값이 맞는 것을 필터링한다
'React > Redux' 카테고리의 다른 글
[React] Redux-Toolkit 설치 / counter app / TodoList (1) | 2023.12.23 |
---|---|
[Redux] Redux를 사용하는 이유 / Redux 실행 과정 이해하기 /Counter 만들기 (1) | 2023.11.20 |