리액트(React)는 현대 웹 애플리케이션을 구축하는 데 널리 사용되는 자바스크립트 라이브러리입니다. 리액트를 사용하면 효율적이고 선언적인 방식으로 사용자 인터페이스(UI)를 구축할 수 있습니다. 이번 글에서는 리액트를 이용하여 작은 CRUD(create, read, update, delete) 애플리케이션인 ‘To-Do List’ 또는 ‘메모 애플리케이션’을 만들어 보겠습니다.
1. 프로젝트 설정하기
먼저 리액트 애플리케이션을 만들기 위해 create-react-app
을 사용할 것입니다. 이것은 리액트 애플리케이션의 기본 설정을 자동으로 처리해주는 도구입니다.
npx create-react-app todo-app
위의 명령어를 실행하면 ‘todo-app’이라는 폴더가 생성되고 리액트 애플리케이션의 기본적인 파일 구조가 생성됩니다. 해당 폴더로 이동한 후, 개발 서버를 시작합시다.
cd todo-app
npm start
2. 프로젝트 구조 이해하기
생성된 애플리케이션의 디렉토리 구조는 다음과 같습니다.
node_modules/
: 설치된 패키지들이 저장되는 디렉토리public/
: 정적 파일들이 저장되는 디렉토리src/
: 리액트 컴포넌트 및 로직이 위치하는 디렉토리package.json
: 프로젝트 관련 메타데이터 및 의존성 정보
3. To-Do List 컴포넌트 생성하기
이제 실제로 To-Do List 애플리케이션을 구성하는 컴포넌트를 만들어보겠습니다. src/
디렉토리로 이동하여 Todo.js
라는 파일을 만들어 줍니다.
touch src/Todo.js
Todo.js
파일에 기본 구조를 추가합니다.
import React, { useState } from 'react';
const Todo = () => {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState('');
const addTodo = () => {
if (!input) return;
setTodos([...todos, input]);
setInput('');
};
const deleteTodo = (index) => {
const newTodos = todos.filter((_, i) => i !== index);
setTodos(newTodos);
};
return (
To-Do List
setInput(e.target.value)}
placeholder="할 일을 입력하세요"
/>
{todos.map((todo, index) => (
-
{todo}
))}
);
};
export default Todo;
위 코드에서는 useState
훅을 사용하여 입력된 텍스트와 To-Do 목록을 관리합니다. 사용자가 새로운 할 일을 추가할 때, 리스트에 해당 아이템을 추가하고 입력 필드는 초기화 됩니다. 삭제 버튼을 클릭할 경우, 특정 할 일을 목록에서 제거합니다.
4. 강화된 Features
단순한 기능 외에도 몇 가지 추가 기능을 구현해 보겠습니다.
4.1. 완료된 To-Do 마킹하기
각 To-Do 항목에 완료 상태를 추가하여 쉽게 처리할 수 있도록 만들 수 있습니다.
const [completed, setCompleted] = useState(Array(todos.length).fill(false));
const toggleComplete = (index) => {
const updatedCompleted = [...completed];
updatedCompleted[index] = !updatedCompleted[index];
setCompleted(updatedCompleted);
};
{todos.map((todo, index) => (
-
{todo}
))}
4.2. 수정 기능 추가하기
To-Do 항목을 수정하는 기능을 추가해보겠습니다.
const editTodo = (index) => {
const newTodo = prompt('수정할 내용을 입력하세요', todos[index]);
if (newTodo) {
const updatedTodos = todos.map((todo, i) => (i === index ? newTodo : todo));
setTodos(updatedTodos);
}
};
{todos.map((todo, index) => (
-
{todo}
))}
5. 리액트 Hooks 활용하기
리액트의 훅스(Hooks)는 함수 컴포넌트에서 상태 및 생명주기를 관리할 수 있게 해줍니다. 이번 프로젝트에서 useState
를 사용하였지만, 더 복잡한 상태 관리를 위해 useReducer
훅을 사용할 수도 있습니다. useReducer
는 상태를 관리하기에 유용하며, 특정 액션에 따라 상태를 업데이트할 수 있습니다.
5.1. useReducer 예제
import React, { useReducer } from 'react';
// 액션 타입 정의
const ADD_TODO = 'ADD_TODO';
const DELETE_TODO = 'DELETE_TODO';
// 초기 상태
const initialState = {
todos: [],
};
// 리듀서 함수
const reducer = (state, action) => {
switch (action.type) {
case ADD_TODO:
return { todos: [...state.todos, action.payload] };
case DELETE_TODO:
return { todos: state.todos.filter((_, index) => index !== action.payload) };
default:
return state;
}
};
const TodoWithReducer = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const [input, setInput] = useState('');
const addTodo = () => {
if (!input) return;
dispatch({ type: ADD_TODO, payload: input });
setInput('');
};
return (
To-Do List with useReducer
setInput(e.target.value)}
placeholder="할 일을 입력하세요"
/>
{state.todos.map((todo, index) => (
-
{todo}
))}
);
};
export default TodoWithReducer;
6. 애플리케이션 스타일링
간단한 To-Do List 애플리케이션은 기본적인 기능을 가지고 있지만, 사용자 경험을 향상시키기 위해 CSS를 사용하여 스타일링할 수 있습니다. src/App.css
파일을 열고 다음과 같이 스타일을 추가해봅시다.
/* App.css */
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}
h1 {
text-align: center;
}
input {
padding: 10px;
font-size: 16px;
width: 200px;
}
button {
padding: 10px;
font-size: 16px;
margin-left: 5px;
}
ul {
list-style-type: none;
padding: 0;
}
li {
background: white;
margin: 5px;
padding: 10px;
border-radius: 5px;
display: flex;
justify-content: space-between;
}
7. 결론
이번 글에서는 리액트로 간단한 CRUD 애플리케이션인 To-Do List를 만들어 보았습니다. 상태 관리에 useState
와 useReducer
를 활용하고, 스타일링을 통해 사용자 경험을 개선할 수 있는 방법을 살펴보았습니다. 이러한 기초를 바탕으로 복잡한 애플리케이션을 구성하는 데 많은 도움이 될 것입니다.
리액트를 통한 개발은 더 많은 확장성과 유지보수성을 제공하므로, 다양한 프로젝트에 응용해보기를 권장합니다.