Front-end/React

[React] 차근차근 Todo List 만들기 with Typescript- (3) ListItem Component

TODO LIST 만들어보기 React with Typescript (리액트 + 타입스크립트) (3)

참고 영상 : https://www.youtube.com/watch?v=ODvirqIC09A

typescript를 사용해서 만들기 때문에 VSCODE를 사용하신다면 tslint라는 확장프로그램을 사용하시면 typescript에 맞지 않는 문법들에 대해 경고 혹은 에러 밑줄을 확인 하실 수 있습니다.

 

ListItem 컴포넌트는 앞서 언급했듯이 Todo List 기능에서 만들어진 각각의 할 일들에 대한 컴포넌트입니다.

우선 TodoListItem.tsx을 만들어주고 기본적인 틀을 만들어봅시다.

 

import React from 'react';

export const TodoListItem = props =>{
	return 		
}

자 여기서 props에서 경고 문구를 볼 수 있을텐데, 그 이유는 props의 타입이 지정되지 않았기 때문입니다. 

그래서 다음과 같이 interface로 타입을 명시 할 수 있게 만들어주고, React.FC에 제네릭 타입으로 방금 만든 interface를 넣어줍니다. 또 props에 todo를 넘겨 줄 것이기 때문에 {todo}를 넣어줍니다.

 

import React from 'react';

interface TodoListItemProps{
    todo: {
        text: string,
        complete: boolean;
    }
}

export const TodoListItem: React.FC<TodoListItemProps> = ({todo}) =>{
	return 		
}

이렇게 하면, TodoListItem이라는 컴포넌트로 todo의 값을 받아 return 할 수 있는 기본 틀을 완성했습니다.

 

ItemList에 들어갈 항목들은 <ul>에 <li>태그를 이용해서 넣어줍니다.

 

export const TodoListItem: React.FC<TodoListItemProps> = ({todo}) =>{
    return <li>
        <label className = {todo.complete ? "complete" : undefined}>
        <input type="checkbox" checked = {todo.complete}/>
        {todo.text}
        </label></li>
};

※ label에 className에 넣어준 삼항식은 아래와 같은 기능을 만들어주기 위해 만들어주었습니다.

기본적으로 TodoListItem Component를 만들었으므로, 이 컴포넌트를 App.tsx에 넣어보겠습니다.

 

우선 App.tsx 파일도 TodoListItem.tsx파일처럼 함수형 컴포넌트 기본틀을 만들어줍니다.

(TodoListItem component를 사용하기 위해 TodoListItem.tsx 파일을 import 해줍니다.)

 

import React from 'react';
import { TodoListItem } from './TodoListItem';

const App: React.FC = () => {
  return 
}

export default App;

 

이제 TodoListItem 컴포넌트를 넣어줄건데, TodoListItem은 todo라는 파라미터를 넘겨 받기 때문에 넘겨줄 아이템을 만들어줘야합니다. 

 

TodoListItem.tsx에서 선언해준 todo 객체와 같은 형식으로 선언하며, 객체배열 형태로 선언하겠습니다.

 

const todos = 
[{text: "밥 먹기", complete: true}, {text: "옷 입기", complete: false}];

 

하지만 여기서도 tslint에 의해 경고문이 뜰텐데, todos의 타입이 정해져있지 않았기 때문입니다.

그렇기 때문에 타입은 인터페이서의 todo와 같은 형태로 정해줘야 하는데, 이 때 App.tsx에 만들어주는 것이 아닌 types.ts파일을 만들어 타입들만 모여 있는 파일을 따로 만들겠습니다.

 

types.d.ts

 

type Todo = {
    text: string;
    complete: boolean;
};

 

types.ts를 사용하기 위해 import를 해줘야하는데, 여기서 types.d.ts로 파일명을 바꾸면 이 파일에 decoration을 해줌으로서 따로 import를 하지 않아도 됩니다.

 

이제 Todo라는 타입을 만들어줬기 때문에 아래와 같이 import없이 App.tsx와 TodoListItem.tsx에 적용시킬 수 있습니다.

 

//App.tsx
const todos: Array<Todo> = [{text: "Walk the dog", complete: true}, {text: "Write App", complete: false}];

//TodoListItem.tsx
interface TodoListItemProps{
    todo: Todo;
}

 

todos를 만들어줌으로서 TodoListItem 컴포넌트를 아래와 같이 App에 구성시킬 수 있습니다.

const todos: Array<Todo> = [{text: "Walk the dog", complete: true}, {text: "Write App", complete: false}];

const App: React.FC = () => {
  return (
    <React.Fragment>
      <TodoListItem todo={todos[0]}/>
      <TodoListItem todo={todos[1]}/>
    </React.Fragment>

   );
}

 

<React.Fragment> 태그를 사용한 이유는? 

 컴포넌트를 넣어줄 때 보통 <div>태그로 감싸져 적용이 됩니다. 이 때 TodoListITem은 <li>태그를 갖고 있는 컴포넌트인데, 만약 <React.Fragment>를 넣어주지 않는다면, 아래와 같이 만들어지기 때문에 리스트 형태로 만들어지지 않을 것입니다.

<ul>
    <div>
      (<li>)<TodoListItem todo={todos[0]}/>(</li>)
    </div>
    <div>
      (<li>)<TodoListItem todo={todos[1]}/>(</li>)
    </div>
</ul>

 

☞  코드 정리

 

App.tsx

 

import React from 'react';
import { TodoListItem } from './TodoListItem';

const todos: Array<Todo> = [{text: "밥 먹기", complete: true}, {text: "옷 입기", complete: false}];

const App: React.FC = () => {
  return (
    <ul>
    <React.Fragment>
      <TodoListItem todo={todos[0]}/>
      <TodoListItem todo={todos[1]}/>
    </React.Fragment>
    </ul>

   );
}

export default App;

 

TodoListItem.tsx

 

import React from 'react'
import "./TodoListItem.css"

interface TodoListItemProps{
    todo: Todo;
}

export const TodoListItem: React.FC<TodoListItemProps> = ({todo}) =>{
    return <li>
        <label className = {todo.complete ? "complete" : undefined}>
        <input type="checkbox" checked = {todo.complete}/>
        {todo.text}
        </label></li>
};

 

코드를 완성한 후 아래와 같은 결과를 보실 수 있습니다.

 

궁금하신 것이 있으시면 바로 댓글 달아주세요!!

 

 

반응형