3 minute read

초반 스타일 작업

  • 책에서는 scss를 사용하여 스타일 작업을 진행하지만 개인적으로는 css가 너무 익숙해서 css를 이용히여 책과 최대한 비슷하게 스타일 작업부터 진행하겠습니다.
      .TodoListItem {padding:1rem; display:flex; align-items:center; border-bottom:0.1rem solid #dddddd;}
      .TodoListItem .checkbox {display:flex; flex-grow:1; align-items:center; cursor: pointer;}
      .TodoListItem .checkbox svg {font-size:2.4rem;}
      .TodoListItem .checkbox .text {margin-left:0.5rem; flex:1 0 0;}
      .TodoListItem .checkbox.checked {color:#868e96; text-decoration: line-through;}
      .TodoListItem .remove svg {font-size:2.4rem; color:#ff6b6b;}
    
  • 해당 css를 추가한 후 컴포넌트 랜더링을 하면 아래와 같은 화면으로 변합니다. React 삽질하기

기본 기능 구현하기_1(App.js)

  • 화면에 나오는 모습은 단순하게 html과 css만을 이용해 만든 화면이므로 텍스트를 입력한 후 추가하거나 기존에 있는 할 일을 삭제하는 기능이 동작하지 않기때문에 해당 기능들을 추가하는 작업을 진행하겠습니다. 먼저 App.js 에서 todos 상태에 따라 달라지는 화면을 표현하기 위해 아래의 이미지와 같이 임시 데이터를 작성합니다. React 삽질하기
      import React, { useState } from 'react';
      import './App.css';
      import TodoTemplate from './components/TodoTemplate';
      import TodoInsert from './components/ToddInsert';
      import TodoList from './components/TodoList';
    
      const App = () => {
      const [todos, setTodos] = useState([
          {
          id: 1,
          text: '리액트 기초 알아보기',
          checked: true,
          },
          {
          id: 2,
          text: '컴포넌트 스타일링 해보기',
          checked: true,
          },
          {
          id: 3,
          text: '일정 관리 앱 만들어보기',
          checked:false,
          }
      ])
      return (
          <>
          <TodoTemplate>
              <TodoInsert />
              <TodoList todos={todos} />
          </TodoTemplate>
          </>
      );
      }
    
      export default App;
    

기본 기능 구현하기_2(TodoList.js)

  • App.js 수정이 끝났다면 두번째로 TodoList.js를 수정합니다. App.js 에서 todos 배열안에 있는 객체들의 고유id, text, checked값을 TodoList에 props 로 전달해주는데 TodoList에서는 해당 값들을 전달받은 후 TodoItem으로 변환하여 랜더링하도록 설정해줘야 합니다. React 삽질하기
      import React from "react";
      import TodoListItem from './TodoListItem';
      import './Todo.css';
    
      const TodoList = ({todos}) => {
          return (
              <div className="TodoList">
                  {todos.map(todo => (
                      <TodoListItem todo={todo} key={todo.id} />
                  ))}
                  {/* <TodoListItem/>
                  <TodoListItem/>
                  <TodoListItem/> */}
              </div>
          );
      };
    
      export default TodoList;
    

    기존에 작성되어있던 TodoListItem 컴포넌트들을 주석처리해준 후 작업을 진행합니다. 먼저 props로 todos를 받아오기 위해 {todos} 를 선언한 후 배열 내장함수 map을 통해 TodoListItem으로 이루어진 배열로 변환하여 랜더링 시켜줍니다. 아래 코드중에 cn 의 경우 classnames 를 사용했습니다. 해당 기능을 사용하기 위해서 터미널에서 npm install classnames 를 사용하여 라이브러리를 설치해줍니다.

기본기능 구현하기_3(TodoListItem.js)

  • TodoList.js까지 수정이 끝났다면 마지막으로 TodoListItem.js에서 todos 를 받아와서 App.js에 입력한 값들을 정상적으로 보여주기 위해 수정해줍니다. React 삽질하기
      import React from "react";
      import {MdRemoveCircleOutline
          , MdCheckBoxOutlineBlank
          , MdCheckBox } from 'react-icons/md';
      import cn from 'classnames';    
      import './Todo.css';
    
      // import './TodoListItem.scss';
      const TodoListItem = ({todo}) => {
          const { text,checked } = todo;
          return(
              <div className="TodoListItem">
                  <div className={cn(`checkbox`, { checked })}>
                      {checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
                      {/* <MdCheckBoxOutlineBlank /> */}
                      <div className="text">{text}</div>
                  </div>
                  <div className="remove">
                      <MdRemoveCircleOutline />
                  </div>
              </div>
          );
      };
    
      export default TodoListItem;
    

    App.js, TodoList.js, TodoListItem.js 파일들을 수정 한 후 컴포넌트가 랜더링 된 모습을 보면 1, 2번 항목의 텍스트와 체크박스 모양이 정상적으로 바뀐 모습을 확인할 수 있습니다. React 삽질하기 텍스트 앞에 체크박스에 체크가 된 텍스트들은 css에서 .TodoListItem .checkbox.checked {color:#868e96; text-decoration: line-through;} 를 통해 color와 text-decration을 통해 효과를 주었습니다.

할 일 추가하기 기능구현_1(TodoInser.js)

  • 임시 데이터들이 정상적으로 출력되지만 input 영역에 텍스트를 입력하고 + 버튼을 눌럿을 때 아래의 할 일 리스트에 추가되는 작업을 진행하겠습니다. 먼저 TodoInsert.js 컴포넌트에서 input 값을 입력했을 때 해당 값을 관리할 수 있도록 value 상태를 정의해줍니다. 그리고 submit 이벤트가 작동할 때 자동으로 추가되는 이벤트값도 설정해줍니다.
      import React, { useState, useCallback } from "react";
      import { IoAdd } from 'react-icons/io5';
    
      const TodoInsert = ({onInsert}) => {
          const [ value, setVlaue ] = useState('');
    
          const onChange = useCallback(e => {
              setVlaue(e.target.value);
          }, []);
    
          const onSubmit = useCallback(
              e => {
                  onInsert(value);
                  setVlaue('');       // value값 초기화
                  // submit 이벤트는 브라우저 새로고침을 진행시키므로 아래 함수 호출
                  e.preventDefault();
              },
              [onInsert, value],
          );
            
    
          return(
              <form className="TodoInsert" onSubmit={onSubmit}>
                  <input 
                  placeholder="할 일을 입력하세요"
                  value={value}
                  onChange={onChange}/>
                  <button type="submit">
                      <IoAdd />
                  </button>
              </form>
          );
      };
    
      export default TodoInsert;  
    

    React 삽질하기 위의 이미지에서도 볼 수 있지만 중간에 submit 이벤트가 실행될 때 브라우저 새로고침을 막기 위한 함수도 추가로 작성해줍니다.

할 일 추가하기 기능구현_2(App.js)

  • TodoInsert.js 수정 작업이 끝난 후 다음번으로는 App.js에서 함수를 추가합니다. 해당 함수에서는 새로운 객체를 추가할 때 마다 id값에 +1을 더해주어 자동적으로 id값이 부여되게 해줍니다.
      import React, { useState , useRef, useCallback } from 'react';
      import './App.css';
      import TodoTemplate from './components/TodoTemplate';
      import TodoInsert from './components/TodoInsert';
      import TodoList from './components/TodoList';
    
      const App = () => {
      const [todos, setTodos] = useState([
          {
          id: 1,
          text: '리액트 기초 알아보기',
          checked: true,
          },
          {
          id: 2,
          text: '컴포넌트 스타일링 해보기',
          checked: true,
          },
          {
          id: 3,
          text: '일정 관리 앱 만들어보기',
          checked:false,
          }
      ])
    
      const nextId = useRef(4);
    
      const onInsert = useCallback(
          text => {
          const todo = {
              id: nextId.current,
              text,
              checked: false,
          };
    
          setTodos(todos.concat(todo));
          nextId.current += 1;      // nextId +1씩 증가
          },
          [todos],
      )
      return (
          <>
          <TodoTemplate>
              <TodoInsert onInsert={onInsert}/>
              <TodoList todos={todos} />
          </TodoTemplate>
          </>
      );
      }
    
      export default App;
    

# 결과보기

  • 소스들이 정상적으로 작성되었다면 테스트를 진행합니다! 할 일을 입력히고 + 버튼을 클릭하면 4번째 줄에 추가로 입력한 텍스트가 추가되는 모습을 볼 수있습니다!

Tags:

Categories:

Updated:

Comments