본문 바로가기

리액트 React/투두앱 만들기

투두앱 만들기 3: 투두 추가하기

반응형

1,2편을 통해 UI부분을 만들었습니다. 이제 실제로 투두를 추가하거나 제거하는등의 기능을 구현할 차례입니다.

 

투두 배열 생성

App.js

import React, { useState, useRef, useCallback } from "react";
import TodoInsert from "./components/TodoInsert/TodoInsert";
import TodoList from "./components/TodoList/TodoList";
import TodoTemplate from "./components/TodoTemplate/TodoTemplate";

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

  const nextId = useRef(0);

  const onInsert = useCallback((text) => {
    const todo = { id: nextId.current, text, checked: false };
    setTodos(todos.concat(todo));
    nextId.current += 1;
  }, [todos]);
  
  return (
    <TodoTemplate>
      <TodoInsert onInsert={onInsert} />
      <TodoList todos={todos} />
    </TodoTemplate>
  );
};

export default App;

추가하는 투두 상태를 useState 를 사용하여 정의하고 TodoList의 props로 전달합니다.

App컴포넌트에서 todos배열에 새 객체를 추가하는 onInsert를 만들고 이 함수를 props로 TodoInsert에 전달합니다.

 

id값은 렌더링이 될필요가 없으므로 useRef를 사용하고 onInsert는 성능을 아낄수 있도록 useCallback을 사용합니다.

 

TodoList.js

import React from "react";
import TodoListItem from "../TodoListItem/TodoListItem";
import { ToDoList } from "./TodoList.styles";

const TodoList = ({ todos }) => {
  return (
    <ToDoList>
      {todos.map((todo) => (
        <TodoListItem todo={todo} key={todo.id} />
      ))}
    </ToDoList>
  );
};

export default TodoList;

전편에서 언급한데로 내장 함수 map을 이용하여 각각의 TodoListItem을 생성하고 보여줍니다.

 

TodoListItem.js

import React from "react";
import {
  MdCheckBox,
  MdCheckBoxOutlineBlank,
  MdRemoveCircleOutline,
} from "react-icons/md";
import "./TodoListItem.styles";
import {
  CheckBox,
  Remove,
  ToDoListItem,
  ToDoText,
} from "./TodoListItem.styles";

const TodoListItem = ({ todo }) => {
  const { text, checked } = todo;

  return (
    <ToDoListItem>
      <CheckBox>
        {checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
        <ToDoText>{text}</ToDoText>
      </CheckBox>
      <Remove>
        <MdRemoveCircleOutline />
      </Remove>
    </ToDoListItem>
  );
};

export default TodoListItem;

 

TodoInsert 버튼 이벤트 생성

App에서 onInsert함수를 TodoInsert컴포넌트에 넣어주었습니다.  TodoInsert컴포넌트에서는 인풋에 입력되는 값을 관리하고 이 값을 onInsert함수 파라미터로 넣어서 호출해주어야 합니다. 

import React, { useState, useCallback } from "react";
import "./TodoInsert.styles";
import { MdAdd } from "react-icons/md";
import { ToDoInput, ToDoInsert, ToDoButton } from "./TodoInsert.styles";

const TodoInsert = ({ onInsert }) => {
  const [value, setValue] = useState("");

  const onChange = useCallback((e) => {
    setValue(e.target.value);
  }, []);

  const onSubmit = useCallback(
      e => {
          onInsert(value);
          setValue('');
          e.preventDefault();
      },
      [onInsert, value]
  )
  
  return (
    <ToDoInsert onSubmit={onSubmit}>
      <ToDoInput
        placeholder="할 일을 작성하세요!"
        value={value}
        onChange={onChange}
      />
      <ToDoButton type="submit">
        <MdAdd />
      </ToDoButton>
    </ToDoInsert>
  );
};

export default TodoInsert;

onSubmit함수가 호출되면 value값을 넣어서 호출하고 현재 value값을 초기화합니다.

onSubmit이벤트는 브라우저를 새로고침시키기 때문에 e.preventDefault()함수를 사용하였습니다. 새로고침을 방지합니다. 

 

$ yarn start

 

반응형