오늘은 나만의 TodoList를 만들어 볼 것이다. 간단한듯 보이지만 초보인 나에게는 조금 어려웠다!
일단 나만의 투두리스트 완성본이다. 기능구현에 집중하느라 디자인은 간단하게 만들어 주었다.
이제 만드는 과정을 이야기 해보겠다! 복습하는 마인드로 쭉 이야기해보겠다!
먼저, 크게 구조를 잡아주었다. 크게 구조를 잡은 다음 중복되는 부분은 나중에 컴포넌트로 분리해줘도 되니깐 크게 세개의 컴포넌트 구조를 생각했다.
<TodoList 구조>
1. App.jsx : 부모 컴포넌트로, input창과 '추가' 버튼이 있는 부분이다.
2. TodoBoard: 투두리스트가 보여질 공간이다.
3. TodoItem: 투두리스트 중 하나의 투두가 차지하는 공간이다.
이렇게 세개의 컴포넌트로 분리했다.
이제 코드를 한번 살펴보겠다. 먼저, App 파일이다. 여기서는 useState 훅을 사용해 상태관리를 해주었다. inputValue(입력필드 현재값)와 todoList(할일 항목들의 배열)을 설정해 주었다. 일단 input창에 값을 입력하면 입력값이 들어왔다는 것을 알기위해 onChange를 input에 써줬다.
onChange는 사용자가 입력 필드의 값을 변경할 때마다 호출되는 함수를 지정한다. 이 함수는 이벤트 객체를 매개변수로 받는다. 그리고 input={inputValue}로 지정해준다. 그래야 값이 inputValue로 들어오게 된다.
그다음 추가버튼을 클릭했을 때 투두가 추가될 수 있게 버튼에 onClick함수를 추가하고, 투두를 추가하는 함수와 삭제하는 함수를 만들어준다. 마지막으로 각각의 자식컴포넌트에게 필요한 함수나 요소를 props를 통해서 전달한다.
import React, { useState } from "react";
import "./App.css";
import TodoBoard from "./components/TodoBoard";
const App = () => {
// state
const [inputValue, setInputValue] = useState("");
const [todoList, setTodoList] = useState([]);
// 투두리스트 추가 기능
const add = () => {
const newTodo = {
id: Date.now(),
text: inputValue,
};
setTodoList([...todoList, newTodo]);
setInputValue("");
};
// 투두리스트 삭제 기능
const deleteTodo = (id) => {
setTodoList(todoList.filter((todo) => todo.id !== id));
};
return (
<div className="body">
<input
className="input"
value={inputValue}
type="text"
onChange={(e) => setInputValue(e.target.value)}
/>
<button className="btn" onClick={add}>
추가
</button>
<TodoBoard todoList={todoList} deleteTodo={deleteTodo} />
</div>
);
};
export default App;
이제 TodoBoard 파일을 보겠다. 여기는 투두리스트가 담기는 공간이자 TodoItem의 부모컴포넌트이다. TodoBoard의 부모컴포넌트에서 todoList(인풋창에 입력한 목록들)와 deleteTodo(삭제하는 함수)를 받았다. TodoBoard에서는 배열인 todoList에 map 매서드를 사용해 새로운 배열을 만들어 TodoItem 컴포넌트에 넣어준다. 여기서 중요한점은 map 매서드를 사용할때는 동적으로 렌더링 되는 것이기 때문에 키값을 설정해주어야 한다.
import React from "react";
import TodoItem from "./TodoItem";
import "../App.css";
const TodoBoard = ({ todoList, deleteTodo }) => {
return (
<div className="board">
<h1>Todo List</h1>
{todoList.map((item) => (
<TodoItem key={item.id} item={item} deleteTodo={deleteTodo} />
))}
</div>
);
};
export default TodoBoard;
마지막으로 TodoItem 파일을 살펴보겠다. 여기는 투두리스트 중에 투두가 하나씩 들어온다. 삭제하는 함수도 받아줌으로써 삭제버튼을 만들고 그 버튼에 onClick 했을 때 삭제하는 함수가 실행되게끔 deleteTodo(item.id)를 써준다.
import React from "react";
import "../App.css";
const TodoItem = ({ item, deleteTodo }) => {
return (
<div className="todo-item">
{item.text}
<button className="deleteBtn" onClick={() => deleteTodo(item.id)}>
삭제
</button>
</div>
);
};
export default TodoItem;
아직 리액트에 대해 잘 모르겠어서 내가 혼자 연습하려고 만든 작은 프로젝트이다. 지금 개인과제를 만드는중인데 너무 어려워서 기본 개념을 더 확실히 익혀보고자 만들어보았다. 유튜브를 참고하여 혼자 만들어보니 많은 도움이 되었다. 상태관리에 사용되는 훅 useState, 컴포넌트 나누기, props 개념 등 어느정도 익힌 것 같다. 이 3가지 개념을 빠삭하게 알아가야 나중에 리액트 숙련단계에 들어갔을 때 따라갈 수 있을 것이다. 나는 아직 실력이 많이 부족해 다른것도 혼자 만들어보려고 계획 중이다ㅜㅜ 아자아자 화이팅!
'개인과제' 카테고리의 다른 글
로그인 기능 구현하기 (0) | 2024.08.27 |
---|---|
리액트로 만든 나만의 포켓몬 도감: 일주일간의 도전과 성장 (4) | 2024.08.26 |
Redux 사용해서 TodoList 만들기! (0) | 2024.08.22 |
Context API로 Props Drilling 해결하기 (0) | 2024.08.21 |
올림픽 메달 트레커 만들기! (0) | 2024.08.14 |