[리액트를 다루는 기술] onToggle 함수를 이용하여 TodoList checkbox 관리

쿼카쿼카·2022년 9월 8일
0

App.js

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

function App() {
  const [todos, setTodos] = useState([
    {
      id: 1,
      text: '리액트의 기초 알아보기',
      checked: true,
    },
    {
      id: 2,
      text: '컴포넌트 스타일링 해보기',
      checked: true,
    },
    {
      id: 3,
      text: '일정 관리 앱 만들기',
      checked: false,
    },
  ]);

  // 고윳값으로 사용될 id
  // ref를 사용하여 변수 담기
  const nextId = useRef(4);

  // props로 전달되는 함수는 useCallback으로 전달
  const onInsert = useCallback(text => {
    const todo = {
      id: nextId.current,
      text,
      checked: false,
    };
    setTodos(todos.concat(todo));
    nextId.current++;
  }, [todos]);

  // remove 함수
  const onRemove = useCallback(id => {
    setTodos(todos.filter(todo => todo.id !== id))
  }, [todos]);

  // checked: true 변경 함수
  const onToggle = useCallback(id => {
    setTodos(todos.map(todo => 
      todo.id === id ? {...todo, checked: true} : todo
    ))
  }, [todos]);

  return (
    <>
      <TodoTemplate>
        <TodoInsert onInsert={onInsert} />
        <TodoList
          todos={todos}
          onRemove={onRemove}
          onToggle={onToggle}
        />
      </TodoTemplate>
    </>
  );
}

export default App;

TodoList.js

import './TodoList.scss';
import TodoListItem from './TodoListItem';

function TodoList({todos, onRemove, onToggle}) {
  return (
    <div className='TodoList'>
      {todos.map(todo => (
        <TodoListItem
          todo={todo}
          key={todo.id}
          onRemove={onRemove}
          onToggle={onToggle}
        />
      ))}
    </div>
  )
}

export default TodoList;

TodoListItem.js

import {
  MdCheckBoxOutlineBlank,
  MdRemoveCircleOutline,
  MdCheckBox
} from 'react-icons/md';
import cn from 'classnames';
import './TodoListItem.scss';

function TodoListItem({todo, onRemove, onToggle}) {
  const {id, text, checked} = todo;
  return (
    <div className='TodoListItem'>
      <div className={cn('checkbox', {checked})} onClick={() => onToggle(id)}>
        {checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
        <div className='text'>{text}</div>
      </div>
      <div className="remove" onClick={() => onRemove(id)}>
        <MdRemoveCircleOutline />
      </div>
    </div>
  )
}

export default TodoListItem

onToggle 함수로 checked: true 변경

  • App.js에서 id와 일치하는 todo를 찾아 {...todo, checked: true} 변경
  • 일치하지 않는 todo는 그대로 두기
profile
쿼카에요

0개의 댓글