728x90
1. 구현 화면
첫화면
추가기능
삭제기능
2. 요구사항과 컴포넌트 구조작성
스터디를 진행하며 가장 많이 배운 것은 개발하는 마음가짐과 단계였다.
개발을 진행하기 앞선 단계를 거의 안하고 바로 코딩을 시작하면서 어떻게 할 것인지 머리속으로만 구상했던 과거를 반성하며 ..
이번에는 요구사항을 분석하고 컴포넌트 구조를 먼저 잡아보았다. 아직 내가 짤 수 있는 기능들에 대해서 자세히 몰라 1, 2 단계로 구성해보았다.
1단계에서는 가장 근본적으로 요구하는 사항 -> TodoList에 내가 할 일을 추가하는 것과 일을 끝내면 삭제할 수 있는 기능을 넣는 것에 집중해보았다.
그렇게 1단계까지 선배림과 여러가지 레퍼런스의 도움을 받아 완성해보았다. (구글과 선배림은 신이야 .. )
아무튼 결론은 어떤 개발을 하더라도 뼈대를 잡는 이 과정이 매우 중요할 것이니 연습 많이 해보아야겠다
componenets에는 2가지를 구성했다
추가를 할 수 있는 TodoCard와 리스트 형태로 나타내는 TodoList 이다.
3. TodoCard.jsx
import React, { useRef, useState } from 'react'
export default function TodoCard({ todoList, setTodoList }) {
const newId = useRef(4);
const [newTodo,setNewTodo] = useState("")
const [newMemo,setNewMemo] = useState("")
//const [newDone,setNewDone] = useState(false)
const addTodo = () => {
const newTodoList = [...todoList];
// newTodoList 배열에 새롭게 받은 todoList를 추가해준다.
const newTodoObj = {
id: newId.current,
//current를 통해 생성될 때마다 다른 Id를 부여할 수 있도록 해준다.
title : newTodo,
content: newMemo,
done : newDone,
}
//Id값 이전값에 대해 +1씩 하기
newId.current++;
newTodoList.push(newTodoObj);
setTodoList(newTodoList);
}
return (
<div className ="card-container">
<div className='titleWrap'>
오늘의 할일을 입력해주세요
</div>
<br/>
<div className="todoWrap">
<div className = "inputTodoWrap">
<input className='input'
placeholder='To-do '
value={newTodo}
onChange={(e) => setNewTodo(e.target.value)}
/>
</div>
<div style = {{marginTop:"20px"}} className = "inputMemoWrap">
<input className='input'
placeholder='메모'
value = {newMemo}
onChange={(e)=> setNewMemo(e.target.value)}
/>
</div>
<div>
<button onClick={addTodo} className = "cardButton">
업로드
</button>
</div>
</div>
</div>
)
}
각 todoitem(반복되는 요소)에 고유한 Id 값을 부여하기 위해 useRef를 사용하였다.
4. TodoList.jsx
import React, { useState } from 'react'
const TodoList= ({ todoList,setTodoList }) => {
const deleteTodo=(id)=>{
// todoList(setTodoList.filter(a => a.id !== it.id));
const newTodoList=todoList.filter(a=>a.id !== id);
setTodoList(newTodoList)
}
return (
<div className='list-container'>
<div className="TodoList">
<h3>Todo List</h3>
<h4>{todoList.length}개의 할 일이 있습니다.</h4>
<div>
{todoList.map((it)=>(
<div className="item-wrap" key={it.id}>
<div>
<input type="checkbox" id="check1" />
<label for ="check1"></label>
</div>
<div>
<div className='title-container'>{it.title} </div>
<div className='memo-container'>{it.content}</div>
</div>
<div>
<button
className = "deleteBtn"
onClick={()=> {deleteTodo(it.id)}}>
삭제</button>
</div>
</div>
))}
</div>
{/* 여기가 끝 !! */}
</div>
</div>
);
}
// TodoList.defaultProps={
// TodoList:[],
// };
export default TodoList;
추가는 map함수, 삭제는 filter함수를 사용하였다.
map 함수는 for문을 이용하지 않고 배열의 원소들 모두 각각 특정한 함수를 적용시킬 수 있다.
filter함수는 이름과 역할이 같다! 주어진 함수를 만족시키는 원소들만으로 구성된 새로운 배열을 반환한다.
5. App.js
import { useRef, useState } from "react";
import TodoCard from "./componenets/TodoCard";
import TodoList from "./componenets/TodoList";
import newList from "./componenets/TodoList";
//dummy data 넣어보기
const dummy = [
{
id: 1,
title : "첫번째 해야할 일 ",
content: "12시, 집 ",
done : true,
},
{
id: 2,
title : "두번째 해야할 일 ",
content: "13시, 학교 ",
done : true,
},
{
id: 3,
title : "세번째 해야할 일 ",
content: "14시, 도서관 ",
done : false,
}
]
function App() {
const [todoList, setTodoList] = useState(dummy);
return (
<div className="App">
<TodoList todoList={todoList} setTodoList={setTodoList}/>
<TodoCard todoList={todoList} setTodoList={setTodoList}/>
</div>
);
}
export default App;
컴포넌트 전달을 잘 하자... !
'FE > React' 카테고리의 다른 글
[리액트 실습] 간단 영화 앱 만들기 6 (헤더 만들기) (1) | 2023.02.26 |
---|---|
[리액트 실습] 간단 영화 앱 만들기 5 (React Routing) (1) | 2023.02.26 |
[리액트 실습] 마켓컬리 클론코딩 1. 헤더 만들기 (0) | 2023.02.03 |
[리액트 실습] 간단 영화 앱 만들기 4 (1-3 코드) (0) | 2023.02.02 |
[리액트 실습] 간단 영화 앱 만들기 3 (components와 props) (1) | 2023.01.24 |