10장 - 일정 관리 웹 애플리케이션 만들기 (1)

sh·2022년 8월 24일
0

프로젝트 준비하기

프로젝트 생성 및 필요한 라이브러리 설치

$ npx create-react-app todo-app 로 프로젝트를 생성한 후 todo-app 디렉터리로 들어가서 필요한 라이브러리를 설치한다.

$ npm install node-ass classnames react-icons

Prettier 설정

프로젝트 최상위 디렉터리에 .prettierrc 파일을 생성한다.

{
  "singleQuote": true,
  "semi": true,
  "useTabs": false,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80
}

index.css 수정

body {
  margin: 0;
  padding: 0;
  background: #e9ecef;
}

App 컴포넌트 초기화

import './App.css';

function App() {
  return <div>Todo App을 만들자!</div>;
}

export default App;

UI 구성하기

  1. TodoTemplate : 화면을 가운데에 정렬시켜 주며, 앱 타이틀(일정 관리)을 보여 준다.
    children으로 내부 JSX를 props로 받아 와서 렌더링 해준다.

  2. TodoInsert : 새로운 항목을 입력하고 추가할 수 있는 컴포넌트이다.
    state를 통해 인풋의 상태를 관리한다.

  3. TodoListItem : 각 할 일 항목에 대한 정보를 보여 주는 컴포넌트이다.
    todo 객체를 props 로 받아와서 상태에 따라 다른 스타일의 UI를 보여준다.

  4. TodoList : todos 배열을 props로 받아 온 후, 이를 배열 내장 함수 map을 사용해서 여러 개의 TodoListItem 컴포넌트로 변환하여 보여준다.

1. TodoTemplate 만들기

//TodoTemplate.js
import React from 'react';
import './TodoTemplate.scss';

const TodoTemplate = ({ children }) => {
  return (
    <div className="TodoTemplate">
      <div className="app-title">일정 관리</div>
      <div className="content">{children}</div>
    </div>
  );
};

export default TodoTemplate;

TodoTemplate 컴포넌트를 App.js에서 불러와 렌더링한다.

// App.js
import './App.css';
import TodoTemplate from './components/TodoTemplate';

function App() {
  return <TodoTemplate>Todo App을 만들자!</TodoTemplate>;
}

export default App;

TodoTemplate의 스타일을 작성한다.

// TodoTemplate.scss
.TodoTemplate {
  width: 512px;
  // width가 주어진 상태에서 좌우 중앙 정렬
  margin-left: auto;
  margin-right: auto;
  margin-top: 6rem;
  border-radius: 4px;
  overflow: hidden;

  .app-title {
    background: #22b8cf;
    color: white;
    height: 4rem;
    font-size: 1.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .content {
    background: white;
  }
}


2. TodoInsert 만들기

TodoInsert.js

import React from 'react';
import { MdAdd } from 'react-icons/md';
import './TodoInsert.scss';

const TodoInsert = () => {
  return (
    <form className="TodoInsert">
      <input placeholder="할 일을 입력하세요" />
      <button type="submit">
        <MdAdd />
      </button>
    </form>
  );
};

export default TodoInsert;

여기서 처음으로 react-icons의 아이콘을 사용한다.
https://react-icons.netlify.com/#/icons/md 에서 사용하고 싶은 아이콘을 고른 뒤, import 구문을 사용하여 불러온 후 컴포넌트처럼 사용한다.

import { 아이콘 이름 } from 'react-icons/md';

TodoInsert를 App에서 불러와 렌더링한다.

import './App.css';
import TodoInsert from './components/TodoInsert';
import TodoTemplate from './components/TodoTemplate';

function App() {
  return (
    <TodoTemplate>
      <TodoInsert />
    </TodoTemplate>
  );
}

export default App;


그 결과 위와 같고 이제 스타일링을 해보자.


// TodoInsert.scss

.TodoInsert {
  display: flex;
  background: #495057;
  input {
    // 기본 스타일 초기화
    background: none;
    outline: none;
    border: none;
    padding: 0.5rem;
    font-size: 1.125rem;
    line-height: 1.5;
    color: white;
    &::placeholder {
      color: #dee2e6;
    }

    // 버튼을 제외한 영역을 모두 차지하기
    flex: 1;
  }
  button {
    // 기본 스타일 초기화
    background: none;
    outline: none;
    border: none;
    background: #868e96;
    color: white;
    padding-left: 1rem;
    padding-right: 1rem;
    font-size: 1.5rem;
    display: flex;
    align-items: center;
    cursor: pointer;
    transition: 0.1s background ease-in;
    &:hover {
      background: #adb5bd;
    }
  }
}

결과는 아래!


3. TodoListItem과 TodoList 만들기

// TodoListItem.js

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

const TodoListItem = () => {
  return (
    <div className="TodoListItem">
      <div className="checkbox">
        <MdCheckBoxOutlineBlank />
        <div className="text">할 일</div>
      </div>
      <div className="remove">
        <MdRemoveCircleOutline />
      </div>
    </div>
  );
};

export default TodoListItem;
// TodoList.js
import React from 'react';
import TodoListItem from './TodoListItem';
import './TodoList.scss';

const TodoList = () => {
  return (
    <div className="TodoList">
      <TodoListItem />
      <TodoListItem />
      <TodoListItem />
    </div>
  );
};

export default TodoList;

// App.js

import './App.css';
import TodoInsert from './components/TodoInsert';
import TodoList from './components/TodoList';
import TodoTemplate from './components/TodoTemplate';

function App() {
  return (
    <TodoTemplate>
      <TodoInsert />
      <TodoList />
    </TodoTemplate>
  );
}

export default App;

스타일링하기

// TodoList.scss

.TodoList {
  min-height: 320px;
  max-height: 513px;
  overflow-y: auto;
}
// TodoListItem.scss

.TodoListItem {
  padding: 1rem;
  display: flex;
  align-items: center; // 세로 중앙 정렬
  &:nth-child(even) {
    background: #f8f9fa;
  }
  .checkbox {
    cursor: pointer;
    flex: 1; // 차지할 수 있는 영역 모두 차지
    display: flex;
    align-items: center;
    svg {
      // 아이콘
      font-size: 1.5rem;
    }
    .text {
      margin-left: 0.5rem;
      flex: 1; // 차지할 수 있는 영역 모두 차지
    }
    // 체크되었을 때 보여 줄 스타일
    &.checked {
      svg {
        color: #22b8cf;
      }
      .text {
        color: #adb5bd;
        text-decoration: line-through;
      }
    }
  }
  .remove {
    display: flex;
    align-items: center;
    font-size: 1.5rem;
    color: #ff6b6b;
    cursor: pointer;
    &:hover {
      color: #ff8787;
    }
  }

  // 엘리먼트 사이사이에 테두리를 넣어 줌
  & + & {
    border-top: 1px solid #dee2e6;
  }
}

여기까지가 컴포넌트 스타일링 끝이다. 이제 다음엔 애플레케이션이 동작할 수 있도록 기능 구현을 하면 된다.

0개의 댓글