React로 Todo 어플 만들기

FlowerNero·2023년 3월 2일
0

react

목록 보기
2/2

단계 1: 프로젝트 세팅

React 프로젝트를 시작하기 위해서는 먼저 Node.js와 npm을 설치해야합니다. 그리고 다음 명령어를 사용하여 React 프로젝트를 생성하세요.

npx create-react-app todo-app

프로젝트를 생성한 후, 프로젝트 폴더로 이동하여 다음 명령어를 입력하여 React 앱을 실행하세요.

cd todo-app
npm start

단계 2: Todo 리스트 구현

App.js 파일을 열고 Todo 리스트를 구현해보겠습니다.

import React, { useState } from 'react';

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

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

  return (
    <div>
      <h1>Todo App</h1>
      <ul>
        {todos.map((todo, index) => (
          <li key={index}>{todo}</li>
        ))}
      </ul>
      <input type="text" placeholder="Add Todo" onKeyUp={(e) => {
        if (e.key === 'Enter') {
          handleAddTodo(e.target.value);
          e.target.value = '';
        }
      }} />
    </div>
  );
}

export default App;

이제 Todo 리스트를 추가할 수 있습니다. 입력 필드에 Todo를 입력하고 엔터를 누르면 리스트에 추가됩니다.

단계 3: Todo 삭제 구현

import React, { useState } from 'react';

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

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

  const handleDeleteTodo = (index) => {
    setTodos(todos.filter((todo, i) => i !== index));
  }

  return (
    <div>
      <h1>Todo App</h1>
      <ul>
        {todos.map((todo, index) => (
          <li key={index}>
            {todo}
            <button onClick={() => handleDeleteTodo(index)}>Delete</button>
          </li>
        ))}
      </ul>
      <input type="text" placeholder="Add Todo" onKeyUp={(e) => {
        if (e.key === 'Enter') {
          handleAddTodo(e.target.value);
          e.target.value = '';
        }
      }} />
    </div>
  );
}

export default App;

이제 Todo 리스트에 추가된 각 항목 옆에 삭제 버튼이 추가됩니다. 클릭하면 항목이 삭제됩니다.

단계 4: 스타일링

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

li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

button {
  background-color: red;
  color: white;
  border: none;
  padding: 5px 10px;
  border-radius: 5px;
  cursor: pointer;
}

단계 5: Todo 수정 기능 추가

import React, { useState } from 'react';

function App() {
  const [todos, setTodos] = useState([]);
  const [editIndex, setEditIndex] = useState(null);
  const [editValue, setEditValue] = useState('');

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

  const handleDeleteTodo = (index) => {
    setTodos(todos.filter((todo, i) => i !== index));
  }

  const handleEditTodo = (index, value) => {
    setEditIndex(index);
    setEditValue(value);
  }

  const handleUpdateTodo = () => {
    const newTodos = [...todos];
    newTodos[editIndex] = editValue;
    setTodos(newTodos);
    setEditIndex(null);
    setEditValue('');
  }

  return (
    <div>
      <h1>Todo App</h1>
      <ul>
        {todos.map((todo, index) => (
          <li key={index}>
            {editIndex === index ? (
              <>
                <input type="text" value={editValue} onChange={(e) => setEditValue(e.target.value)} />
                <button onClick={handleUpdateTodo}>Update</button>
              </>
            ) : (
              <>
                {todo}
                <div>
                  <button onClick={() => handleEditTodo(index, todo)}>Edit</button>
                  <button onClick={() => handleDeleteTodo(index)}>Delete</button>
                </div>
              </>
            )}
          </li>
        ))}
      </ul>
      <input type="text" placeholder="Add Todo" onKeyUp={(e) => {
        if (e.key === 'Enter') {
          handleAddTodo(e.target.value);
          e.target.value = '';
        }
      }} />
    </div>
  );
}

export default App;

이제 각 Todo 항목에 대해 수정 버튼이 추가되었습니다. 클릭하면 Todo 항목이 입력 필드로 대체되며, 업데이트 버튼을 누르면 수정된 Todo가 저장됩니다.

단계 6: Todo 완료 기능 추가

import React, { useState } from 'react';

function App() {
  const [todos, setTodos] = useState([]);
  const [editIndex, setEditIndex] = useState(null);
  const [editValue, setEditValue] = useState('');

  const handleAddTodo = (todo) => {
    setTodos([...todos, { text: todo, completed: false }]);
  }

  const handleDeleteTodo = (index) => {
    setTodos(todos.filter((todo, i) => i !== index));
  }

  const handleEditTodo = (index, value) => {
    setEditIndex(index);
    setEditValue(value);
  }

  const handleUpdateTodo = () => {
    const newTodos = [...todos];
    newTodos[editIndex].text = editValue;
    setTodos(newTodos);
    setEditIndex(null);
    setEditValue('');
  }

  const handleCompleteTodo = (index) => {
    const newTodos = [...todos];
    newTodos[index].completed = true;
    setTodos(newTodos);
  }

  return (
    <div>
      <h1>Todo App</h1>
      <ul>
        {todos.map((todo, index) => (
          <li key={index} className={todo.completed ? 'completed' : ''}>
            {editIndex === index ? (
              <>
                <input type="text" value={editValue} onChange={(e) => setEditValue(e.target.value)} />
                <button onClick={handleUpdateTodo}>Update</button>
              </>
            ) : (
              <>
                {todo.text}
                <div>
                  {!todo.completed && (
                    <>
                      <button onClick={() => handleEditTodo(index, todo.text)}>Edit</button>
                      <button onClick={() => handleDeleteTodo(index)}>Delete</button>
                      <button onClick={() => handleCompleteTodo(index)}>Complete</button>
                    </>
                  )}
                </div>
              </>
            )}
          </li>
        ))}
      </ul>
      <input type="text" placeholder="Add Todo" onKeyUp={(e) => {
        if (e.key === 'Enter') {
          handleAddTodo(e.target.value);
          e.target.value = '';
        }
      }} />
    </div>
  );
}

export default App;

이제 각 Todo 항목에 대해 완료 버튼이 추가되었습니다. 클릭하면 Todo 항목이 완료되며, 완료된 Todo 항목은 취소선으로 표시됩니다.

단계 7: Local Storage에 Todo 저장

이번 단계에서는 Todo 항목을 Local Storage에 저장하여, 페이지를 새로고침해도 Todo 항목이 유지되도록 하겠습니다

import React, { useState, useEffect } from 'react';

function App() {
  const [todos, setTodos] = useState([]);
  const [editIndex, setEditIndex] = useState(null);
  const [editValue, setEditValue] = useState('');

  useEffect(() => {
    const storedTodos = JSON.parse(localStorage.getItem('todos'));
    if (storedTodos) {
      setTodos(storedTodos);
    }
  }, []);

  useEffect(() => {
    localStorage.setItem('todos', JSON.stringify(todos));
  }, [todos]);

  const handleAddTodo = (todo) => {
    setTodos([...todos, { text: todo, completed: false }]);
  }

  const handleDeleteTodo = (index) => {
    setTodos(todos.filter((todo, i) => i !== index));
  }

  const handleEditTodo = (index, value) => {
    setEditIndex(index);
    setEditValue(value);
  }

  const handleUpdateTodo = () => {
    const newTodos = [...todos];
    newTodos[editIndex].text = editValue;
    setTodos(newTodos);
    setEditIndex(null);
    setEditValue('');
  }

  const handleCompleteTodo = (index) => {
    const newTodos = [...todos];
    newTodos[index].completed = true;
    setTodos(newTodos);
  }

  return (
    <div>
      <h1>Todo App</h1>
      <ul>
        {todos.map((todo, index) => (
          <li key={index} className={todo.completed ? 'completed' : ''}>
            {editIndex === index ? (
              <>
                <input type="text" value={editValue} onChange={(e) => setEditValue(e.target.value)} />
                <button onClick={handleUpdateTodo}>Update</button>
              </>
            ) : (
              <>
                {todo.text}
                <div>
                  {!todo.completed && (
                    <>
                      <button onClick={() => handleEditTodo(index, todo.text)}>Edit</button>
                      <button onClick={() => handleDeleteTodo(index)}>Delete</button>
                      <button onClick={() => handleCompleteTodo(index)}>Complete</button>
                    </>
                  )}
                </div>
              </>
            )}
          </li>
        ))}
      </ul>
      <input type="text" placeholder="Add Todo" onKeyUp={(e) => {
        if (e.key === 'Enter') {
          handleAddTodo(e.target.value);
          e.target.value = '';
        }
      }} />
    </div>
  );
}

export default App;

이제 Todo 항목이 Local Storage에 저장되며, 페이지를 새로고침해도 Todo 항목이 유지됩니다.

0개의 댓글