ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React TodoList] 컴포넌트 기능 구현하기 - 추가
    React/일정관리 프로젝트 2023. 3. 14. 17:37

    컴포넌트 기능 구현하기

     

    리스트 화면에 출력

    App.js에서 todo 상태 사용하기

    import React , { useState } from "react";
    import TodoTemplate from "./TodoTemplate";
    import TodoInsert from "./TodoInsert";
    import TodoList from "./TodoList";
    
    const App = () => {
      const [todos,setTodos] = useState([
        {
          id :1,
          text : '리액트의 기초 알아보기',
          checked : true },
        {
          id :2,
          text : '리액트의 스타일링해 보기',
          checked : true },
        {
          id :3,
          text : '일정 관리 앱 만들어 보기',
          checked : false },
        {
          id :4,
          text : '리액트 컴포넌트 이해하기',
          checked : false },
        {
          id :5,
          text : '리액트 네이티브 기초 알아보기',
          checked : false },    
    ]);
    
    
      return (
      <TodoTemplate> 
          <TodoInsert />
          <TodoList todos={todos}/>
      </TodoTemplate>
      )
    }
    
    export default App;

     

    Todolist.js

    import React from 'react';
    import TodoListItem  from './TodoListItem';
    import './TodoList.scss'
    
    const TodoList = ({todos}) => {
      return (
        <div className='TodoList'>
          {todos.map(todo => (
             <TodoListItem todo={todo} key={todo.id} /> 
          ))}  
        </div>
      );
    };
    
    export default TodoList;

     

     

    todoListItem.js

    import React from 'react';
    import { 
      MdOutlineCheckBoxOutlineBlank,
      MdOutlineCheckBox,
      MdRemoveCircleOutline } from "react-icons/md";
    import cn from 'classnames'
    import './TodoListItem.scss'
    
    
    const TodoListItem = ({todo}) => {
      const {id,text,checked} =todo;
      return (
        <div className='TodoListItem'>
          <div className={cn('checkbox',{checked})} >
            {checked? <MdOutlineCheckBox /> : <MdOutlineCheckBoxOutlineBlank />}
            <div className='text'>{text}</div>
          </div>
          <div className='remove'>
            <MdRemoveCircleOutline />
          </div>
        </div>
      );
    };
    
    export default TodoListItem;

     

     

    항목 추가 기능 구현

     

    - TodoInsert 컴포넌트에서 input 값을 useState를 사용해서 value라는 상태 저장

    - 컴포넌트가 한 번 함수를 만들고 재사용할 수 있도록 useCallback Hook을 사용한다.

     

     

    TodoInsert.js

    import React, { useCallback,useState } from 'react';
    import { MdAddComment } from "react-icons/md";
    import './TodoInsert.scss'
    
    const TodoInsert = ({onInsert}) => {
      const [value,setValue] = useState('')
      const onChange = useCallback(e => {
        setValue(e.target.value)
      },[])
      
    
      return (
        <form className='TodoInsert' >
          <input placeholder='할 일을 입력하세요' value={value} onChange={onChange} />
          <button type="submit">
            <MdAddComment />
          </button>
          
        </form>
      );
    };
    
    export default TodoInsert;

     

    todo 배열에 새 객체 추가하기

     

    - onInsert 함수를 생성하여 새로운 객체의 id 값 +1, id 값은 useRef를 사용한다.

      그 이유는 id는 렌더링 되는 정보가 아니기 때문에 useState 대신 useRef를 사용한다.

     

    - useCallback을 사용하여 props로 전달해야 할 함수를 감싸서 컴포넌트의 성능을 아낄 수 있다. 

     

     

    app.js

    import React , {useCallback, useState,useRef} from "react";
    import TodoTemplate from "./TodoTemplate";
    import TodoInsert from "./TodoInsert";
    import TodoList from "./TodoList";
    
    const App = () => {
      const [todos,setTodos] = useState([
        {
          id :1,
          text : '리액트의 기초 알아보기',
          checked : true },
        {
          id :2,
          text : '리액트의 스타일링해 보기',
          checked : true },
        {
          id :3,
          text : '일정 관리 앱 만들어 보기',
          checked : false },
        {
          id :4,
          text : '리액트 컴포넌트 이해하기',
          checked : false },
        {
          id :5,
          text : '리액트 네이티브 기초 알아보기',
          checked : false },    
    ]);
    const nextId = useRef(6);
    
    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} onRemove={onRemove} onToggle={onToggle} />
      </TodoTemplate>
      )
    }
    
    export default App;

     

    todoInsert.js에서 onSubmit 이벤트 설정

    - onClick 대신 onSubmit을 사용하는 이유는 클릭과 엔터 모두 반응하기 위해서이다.

     

     

    import React, { useCallback,useState } from 'react';
    import { MdAddComment } from "react-icons/md";
    import './TodoInsert.scss'
    
    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 (
        <form className='TodoInsert' onSubmit={onSubmit}>
          <input placeholder='할 일을 입력하세요' value={value} onChange={onChange} />
          <button type="submit">
            <MdAddComment />
          </button>
          
        </form>
      );
    };
    
    export default TodoInsert;
Designed by Tistory.