[React 기초] Todo list 만들기 :: 2) App, Container, Titlebar
도깨비젤리
·2021. 6. 12. 16:49
개발 환경 설정
npm create-react-app TODO
npm install sass --save
npm install uuid
create-react-app 을 사용해서 React를 준비해준다. 추가로 나는 css 대신에 scss를 사용할 것이기 때문에, sass도 준비해두자. Vue와 달리 React에서 sass를 사용할 때 sass-loader 같은 패키지를 준비하지 않아도 된다는 점이 좋았다.
추가로 uuid 라이브러리를 가져오자. uuid는 Universal Unique Identifier (범용 단일 식별자)의 약어로, 호출한다면 랜덤으로 생성된 문자열을 반환해준다. 컴포넌트에 key값이 필요할 때 고유한 값으로 설정하기에 딱 좋다.
uuid를 안 쓴다면, id가 필요할 때 max_int 값을 0으로 설정한 다음, Todo Item이 추가될때마다 max_int를 증가시키고, 그 증가된 값을 id로 지정할 수도 있다. 그런데 max_int 값은 항상 페이지가 refresh 되거나, 연결이 끊어진다면 다시 호출되어 0으로 초기화 된다. 그런데 localStorage에는 이미 id가 0인 item이 있다면....?
Todo Items와 함께 max_int도 localStorage에 저장하면 이런 문제를 해결 할 수는 있지만, 이건 별로 스마트하지도 않고, 부서지기도 쉬운 미봉책이다. 그렇기 때문에 uuid라는 잘 만들어진 바퀴를 가져다 씁시다.
App.js
import './sass/TODO.scss'
import Container from './components/Container.js'
function App() {
return (
<>
<Container></Container>
</>
);
}
export default App;
create-react-app으로 프로젝트를 시작하면 최상위 컴포넌트로 설정되는 곳이다. 여기서 바로 템플릿을 구성해도 되지만, 개인적으로 App이 너무 길어지면 좋지 않다고 생각한다. 코드가 길어져서 보기도 싫고, 추후 확장성을 고려하면 최상위 계층은 어떤 컴포넌트가 어디에 있는지 정도만 알려줘야한다고 생각한다.
그렇기 때문에, 여기서는 scss 파일만 import 해주고, Todo list의 구현은 Container 컴포넌트에게 맡깁시다.
Container.js
import React, {useEffect, useState} from 'react'
import Titlebar from './Titlebar.js'
import InputForm from './InputForm.js'
import TODOS from './TODOS.js'
function Container (){
// todos의 상태 관리
const [todos, setTodos] = useState([])
useEffect(()=>{
const TODOS = localStorage.getItem('TODOS')
if(TODOS===null){
localStorage.setItem('TODOS','[]')
} else{
const parseTODOS = JSON.parse(TODOS)
setTodos(parseTODOS)
}
},[])
function addTodo(newTodo,id,completed){
setTodos([...todos, {'TODO' : newTodo, 'id':id,completed:completed}])
}
function getTodos(){
return todos
}
function delTodos(id){
const result = todos.filter(({id: todoId})=>id !==todoId)
const stringTodo = JSON.stringify(result)
localStorage.setItem('TODOS',stringTodo)
setTodos(result)
}
return(
<div className="container">
<Titlebar/>
<InputForm
addTodo={addTodo}
/>
<hr></hr>
<TODOS
getTodos={getTodos}
delTodos={delTodos}
></TODOS>
</div>
)
}
export default Container
Container의 역할
- Todo list의 탬플릿
- Todo list의 상태 관리
Container 컴포넌트가 Todo list의 CRD 기능을 하는 함수들을 다 짊어지고 있다. 하위 컴포넌트인 InputForm, TODOS 모두 Todo list의 상태와 밀접한 관련이 있으므로, 컴포넌트 각각이 상태를 가지고 있는 것보다는, 상위 컴포넌트인 Container가 두 컴포넌트에게 props로 전달하는 데이터 구조를 가지고 있어야함이 더 적절하다.
사용자에게 받은 입력을 바탕으로 Item을 생성 (Create) 하는 기능을 가진 InputForm 컴포넌트에 Create 기능을 가진 addTodo 함수를 props로 전달하고, 저장되어있는 Item을 읽고 (Read) 삭제 (Delete)하는 기능을 가진 TODOS 컴포넌트에 Read 기능을 가진 getTodos와 Delete 기능을 가진 delTodos를 props로 전달하자.
Titlebar.js
import React from 'react'
function Titlebar (){
return(
<nav>
<h1>오늘 할 일</h1>
</nav>
)
}
export default Titlebar
Titlebar.js의 역할
- 제목 표시
nav 태그를 이용해서 제목을 띄워준다.
nav 태그에 padding를 주어 h1 태그가 화면 밖으로 삐쳐나가지 않게 방지 한 것 외에는 별거 없다.
'웹 > React' 카테고리의 다른 글
[Next.js] Data Fetching의 방법들 (1) | 2022.09.20 |
---|---|
JSX에서 list를 랜더링 하는 방식 (0) | 2022.04.03 |
[React 기초] Todo list 만들기 :: 3)InputForm,TODOS (0) | 2021.06.12 |
[React 기초] Todo list 만들기 :: 1) Intro (0) | 2021.06.12 |