고양이와 코딩
[React] 친구가 말아준 TodoList 과제 본문
728x90
뒤늦게 포스팅하는, 친구가 내준 투두리스트 과제!
https://github.com/ovovvvvv/React-Todo
GitHub - ovovvvvv/React-Todo: 투두리스트로 배우는 리액트
투두리스트로 배우는 리액트. Contribute to ovovvvvv/React-Todo development by creating an account on GitHub.
github.com
리액트를 너무 어렵게 생각하는 저를 위해 친구가 과제형식으로 레포지토리를 파 주었습니다 (동기 잘만났다..)
컴포넌트는 TodoList, TodoItem만 따로 분리했고, 일단 App파일에 대부분의 로직을 작성했습니다!
import { useState, useCallback, useRef, ChangeEvent } from "react";
import TodoList from "./components/TodoList";
import "./App.css";
export interface TodoProps {
id: number;
text: string;
state: boolean;
}
const App: React.FC = () => {
const [todos, setTodos] = useState<TodoProps[]>([
{
id: 0,
text: "오늘은",
state: false,
},
{
id: 1,
text: "초코케익 먹는날",
state: false,
},
{
id: 2,
text: "세수하기",
state: false,
},
]);
const [inputText, setInputText] = useState("");
const nextId = useRef<number>(3);
// useState 생명주기 ?
const onInsert = useCallback(() => {
setTodos((prevTodos) => {
const todo = {
id: nextId.current,
text: inputText,
state: false,
};
return [...prevTodos, todo];
});
setInputText("");
nextId.current += 1;
}, [inputText]);
const onClick = useCallback(() => {
onInsert();
}, [onInsert]);
const onChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setInputText(e.target.value);
}, []);
const handleComplete = useCallback(
(id: number) => {
setTodos((prevTodos) =>
prevTodos.map((todo) =>
todo.id === id ? { ...todo, state: !todo.state } : todo
)
);
},
[todos]
);
const handleDelete = useCallback(
(id: number) => {
setTodos(todos.filter((todo) => todo.id !== id));
},
[todos]
);
return (
<div className="container">
<h1>투두리스트 ~~~ 🍀</h1>
<input type="text" onChange={onChange} value={inputText} />
<button type="submit" onClick={onClick}>
+
</button>
<TodoList
todos={todos}
handleComplete={handleComplete}
handleDelete={handleDelete}
/>
</div>
);
};
export default App;
import TodoItem from "./TodoItem";
import { TodoProps } from "../App";
type HandleCompleteType = (id: number) => void;
type HandleDeleteType = (id: number) => void;
interface TodoListProps {
todos: TodoProps[];
handleComplete: HandleCompleteType;
handleDelete: HandleDeleteType;
}
const TodoList: React.FC<TodoListProps> = ({
todos,
handleComplete,
handleDelete,
}) => {
return (
<div className="todoList">
{todos.map((todo) => (
<TodoItem
key={todo.id}
todo={todo}
handleDelete={handleDelete}
handleComplete={handleComplete}
/>
))}
</div>
);
};
export default TodoList;
import { TodoProps } from "../App";
interface TodoItemProps {
todo: TodoProps;
handleComplete: (id: number) => void;
handleDelete: (id: number) => void;
}
const TodoItem: React.FC<TodoItemProps> = ({
todo,
handleComplete,
handleDelete,
}) => {
const { id, text, state } = todo;
return (
<div>
<li key={id}>
{text}
<button onClick={() => handleComplete(id)}>
{state ? "완료됨" : "미완료"}
</button>
<button onClick={() => handleDelete(id)}>삭제</button>
</li>
</div>
);
};
export default TodoItem;
이렇게 간단하게 투두 추가, 완료 체크, 삭제 기능을 하는 투두리스트를 만들었습니다
✔️ 친구의 리뷰
- useCallBack을 꼭 써야 하는 상황에만 사용하기
- 변수명 공식문서에서 권장하는 방식으로 지어라 (handle 어쩌고)
- useRef를 사용한 이유? (알고 써라)
- 구조분해할당 사용한 부분은 마음에든다
기술이 많이 부족해서 스스로 최대한 이만큼 구현하는데도 꽤 많은 시간이 들다보니,,,
추가구현을 하지 못했고, 컴포넌트도 제대로 분리하지 못했습니다!
다음 포스팅에서는 추가구현 + 컴포넌트 분리와 함께 여유가 된다면 스타일드컴포넌트 사용도 해보려고 합니다!
'todoList' 카테고리의 다른 글
[React] 투두리스트를 만들어보자 ! - 1 (1) | 2024.02.14 |
---|