728x90
반응형
Lv2
- React + redux-toolkit를 이용한 TodoList를 만듭니다.
- Todo를 Create, Delete, Update(완료/취소)가 가능해야 합니다.
- Lv1의 코드를 고쳐서 만듭니다.
Keyword
전역 상태 관리, redux
1. props drilling과 useState로 관리했던 todos 데이터 -> 리덕스 툴킷 => App.tsx 간단해짐
[App.tsx]
function App() {
return (
<StDiv>
<StHeader>
<p>My Todo List📝</p>
<p>React</p>
</StHeader>
<StMain>
<InputForm />
<Content isDone={false} />
<Content isDone={true} />
</StMain>
<footer></footer>
</StDiv>
);
}
2. 리덕스 작업
1) yarn 추가
yarn add react-redux @reduxjs/toolkit
2) redux폴더에 config / modules 파일 생성
config - [configStore.tsx]
import { configureStore } from '@reduxjs/toolkit';
import todos from '../modules/todoSlice';
import { useDispatch } from 'react-redux';
const store = configureStore({
reducer: { todos },
});
//useSelector state 타입 정의
export type RootState = ReturnType<typeof store.getState>;
//useDispatch
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch: () => AppDispatch = useDispatch;
export default store;
▶ store : 전역에서 state 관리해주는 객체 형태의 공간
3) 리덕스툴킷에서 제공하는 configureStore 사용
- 타입스크립트 포인트 : useSelector & useDispatch 의 state 타입 정의
* js
const data = useSelector((state)=> state.todos)
const dispatch = useDispatch();
* ts (타입선택)
const data = useSelector((state:RootState) => state.todos)
const dispatch = useAppDispatch();
modules - [todoSlice.tsx]
import { createSlice } from '@reduxjs/toolkit';
import uuid from 'react-uuid';
//interface 사용 --> 가독성과 유지보수에 좋음
export interface Todo {
id: string;
title: string;
content: string;
isDone: boolean;
}
//초기 상태 정의
const initialState: Todo[] = [
{
id: uuid(),
title: '제목1',
content: '내용1',
isDone: false,
},
{
id: uuid(),
title: '제목2',
content: '내용2',
isDone: true,
},
];
//타입추론으로 타입지정을 안해도 되는 경우가 있음 : action.payload같은 경우
const todoSlice = createSlice({
name: 'todos',
initialState,
reducers: {
addTodo: (state, action) => {
state.push(action.payload);
},
removeTodo: (state, action) => {
return state.filter((item) => item.id !== action.payload);
},
switchTodo: (state, action) => {
return state.map((item) => {
if (item.id === action.payload) {
return { ...item, isDone: !item.isDone };
} else {
return item;
}
});
},
},
});
export const { addTodo, removeTodo, switchTodo } = todoSlice.actions;
export default todoSlice.reducer;
1) interface 사용해서 todo데이터 타입 정의2) 초기 상태 정의
3) 타입추론으로 타입지정을 안 해도 되는 경우가 있음 : action.payload 같은경우
-> 나중에 오류 발생 시 수정
[Content.tsx]
import React from 'react';
import styled from 'styled-components';
import { useSelector } from 'react-redux';
import { useAppDispatch } from '../redux/config/configStore';
import { RootState } from '../redux/config/configStore';
import { removeTodo, switchTodo } from '../redux/modules/todoSlice';
type Props = {
isDone: boolean;
};
function Content({ isDone }: Props) {
const todos = useSelector((state: RootState) => state.todos);
const dispatch = useAppDispatch();
return (
<>
<StDiv> {isDone ? '✌️Done✌️' : '✍️Working'}</StDiv>
<StDivLayout>
{todos
.filter((item) => item.isDone === isDone)
.map((todo) => {
return (
<StDivTodo key={todo.id}>
<h3>{todo.title}</h3>
<p>{todo.content}</p>
<StDivBtn>
<DeleteButton
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
dispatch(removeTodo(todo.id));
}}
>
삭제
</DeleteButton>
<StateButton
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
dispatch(switchTodo(todo.id));
}}
>
{isDone ? '취소' : '완료'}
</StateButton>
</StDivBtn>
</StDivTodo>
);
})}
</StDivLayout>
</>
);
}
export default Content;
1) useSelector와 dispatch 설정
const todos = useSelector((state: RootState) => state.todos);
const dispatch = useAppDispatch();
2) dispatch로 삭제할 데이터의 id 전달하기
<DeleteButton
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
dispatch(removeTodo(todo.id));
}}
> 삭제 </DeleteButton>
★ ★ ★
참고 자료 : https://redux-toolkit.js.org/tutorials/typescript
★ ★ ★
반응형
'TIL :: Today I Learned' 카테고리의 다른 글
TypeScript : 투두리스트 만들기 (4단계 - Thunk + Axios ) (0) | 2023.12.17 |
---|---|
TypeScript : 투두리스트 만들기 (3단계 - Json-server) (0) | 2023.12.16 |
TypeScript : 투두리스트 만들기 (1단계 - React Props) (0) | 2023.12.14 |
리액트 : Modal 모달 팝업 외부 영역 클릭시 닫기 기능 + 배경 스크롤 막기 (0) | 2023.12.11 |
리액트 : 파이어베이스 데이터 저장 후 홈 화면 리랜더링하기 (0) | 2023.12.11 |