리액트 강좌: To Do 앱 예제, UI 구현하기

안녕하세요. 이번 글에서는 리액트로 To Do 앱을 만드는 방법에 대해 알아보겠습니다. 이 강좌에서는 UI/UX 설계와 함께 기능 구현까지 다룰 것입니다. 리액트는 컴포넌트 기반의 자바스크립트 라이브러리로, 동적인 사용자 인터페이스를 쉽게 만들 수 있도록 도와줍니다.

프로젝트 준비하기

시작하기 전에, 프로젝트의 기본 설정을 해야 합니다. 다음과 같은 과정으로 개발 환경을 구축할 수 있습니다.

npx create-react-app my-todo-app

위 명령어를 실행하면 my-todo-app이라는 폴더에 리액트 앱의 기본 템플릿이 생성됩니다. 생성된 폴더로 이동하고 앱을 실행해 보겠습니다.

cd my-todo-app
npm start

브라우저에서 http://localhost:3000에 접속하면 기본 리액트 앱이 실행되는 것을 볼 수 있습니다.

컴포넌트 구조 설계하기

To Do 앱의 기본적인 기능은 할 일을 추가하고, 완료 상태를 토글하며, 삭제하는 것입니다. 아래와 같은 컴포넌트 구조를 설계할 수 있습니다.

  • App: 애플리케이션의 루트 컴포넌트
  • TodoList: 할 일 목록을 표시하는 컴포넌트
  • TodoItem: 각 할 일 항목을 표시하는 컴포넌트
  • AddTodo: 할 일을 추가하는 폼 컴포넌트

컴포넌트 구현하기

이제 각 컴포넌트를 구현해 보겠습니다.

1. App 컴포넌트

먼저 App.js 파일을 열어 기본 상태를 정의해 보겠습니다.

import React, { useState } from 'react';
import TodoList from './components/TodoList';
import AddTodo from './components/AddTodo';

const App = () => {
    const [todos, setTodos] = useState([]);

    const addTodo = (todo) => {
        setTodos([...todos, todo]);
    };

    const toggleComplete = (index) => {
        const newTodos = todos.map((todo, i) => {
            if (i === index) {
                return { ...todo, completed: !todo.completed };
            }
            return todo;
        });
        setTodos(newTodos);
    };

    const deleteTodo = (index) => {
        const newTodos = todos.filter((_, i) => i !== index);
        setTodos(newTodos);
    };

    return (
        <div className="App">
            <h1>To Do List</h1>
            <AddTodo addTodo={addTodo} />
            <TodoList todos={todos} toggleComplete={toggleComplete} deleteTodo={deleteTodo} />
        </div>
    );
};

export default App;

2. TodoList 컴포넌트

다음으로 TodoList.js를 구현합니다. 이 컴포넌트는 할 일 목록을 렌더링합니다.

import React from 'react';
import TodoItem from './TodoItem';

const TodoList = ({ todos, toggleComplete, deleteTodo }) => {
    return (
        <ul>
            {todos.map((todo, index) => (
                <TodoItem 
                    key={index} 
                    todo={todo} 
                    toggleComplete={() => toggleComplete(index)} 
                    deleteTodo={() => deleteTodo(index)} 
                />
            ))}
        </ul>
    );
};

export default TodoList;

3. TodoItem 컴포넌트

이제 각 할 일 항목을 표현하는 TodoItem.js를 작성합니다.

import React from 'react';

const TodoItem = ({ todo, toggleComplete, deleteTodo }) => {
    return (
        <li style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
            {todo.text}
            <button onClick={toggleComplete}>완료</button>
            <button onClick={deleteTodo}>삭제</button>
        </li>
    );
};

export default TodoItem;

4. AddTodo 컴포넌트

마지막으로, 할 일을 추가하는 폼을 구현합니다.

import React, { useState } from 'react';

const AddTodo = ({ addTodo }) => {
    const [inputValue, setInputValue] = useState('');

    const handleSubmit = (e) => {
        e.preventDefault();
        if (inputValue.trim()) {
            addTodo({ text: inputValue, completed: false });
            setInputValue('');
        }
    };

    return (
        <form onSubmit={handleSubmit}>
            <input 
                type="text" 
                value={inputValue} 
                onChange={(e) => setInputValue(e.target.value)} 
                placeholder="할 일을 입력하세요" 
            />
            <button type="submit">추가</button>
        </form>
    );
};

export default AddTodo;

스타일링 추가하기

이제 기본적인 기능이 구현되었으니, CSS를 사용해 UI를 더욱 아름답게 꾸며봅시다. App.css 파일에 다음의 스타일을 추가합니다.

body {
    font-family: 'Arial', sans-serif;
    background-color: #f4f4f4;
}

.App {
    max-width: 600px;
    margin: 50px auto;
    padding: 20px;
    background: white;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

h1 {
    text-align: center;
}

form {
    display: flex;
    justify-content: space-between;
    margin-bottom: 20px;
}

input[type="text"] {
    flex: 1;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 4px;
}

button {
    padding: 10px 15px;
    margin-left: 10px;
    border: none;
    border-radius: 4px;
    background: #4A90E2;
    color: white;
    cursor: pointer;
}

button:hover {
    background: #357ABD;
}

ul {
    list-style-type: none;
    padding: 0;
}

테스트 및 배포

이제 앱이 완성되었으니, 테스트 및 배포를 진행할 수 있습니다. npm run build 명령어를 통해 프로덕션 빌드를 생성할 수 있습니다.

npm run build

생성된 build 폴더를 서버에 배포하면 여러분의 To Do 앱이 세상에 선보이게 됩니다.

결론

이번 강좌에서는 리액트를 사용하여 기본적인 To Do 앱을 구현해보았습니다. 리액트의 컴포넌트 기반 아키텍처와 상태 관리를 활용하여 효율적으로 UI를 구축할 수 있었습니다. 다음에는 더 복잡한 기능 추가나 상태 관리 라이브러리인 Redux를 사용해보는 것도 추천드립니다.

리액트를 통한 프로젝트 개발은 반복과 개선의 과정입니다. 계속해서 학습하고 실습하여 여러분만의 멋진 애플리케이션을 만들어보세요!