본문 바로가기
React/Keeper-app | To-Do-app clone

[To-Do App] 아이템 지우기 |

by CodeMia 2022. 4. 16.

앞 포스트에서 아이템을 클릭하면 취소선이 그어지는 것을 연습했다.

 

 

 

이제는 다른 컴포넌트의 array에 있는 아이템을 지우는 법에 대해 알아보자. 

 

 


 

시작 코드 

App.js 

import React, { useState } from "react";
import ToDoItem from "./ToDoItem";

function App() {
const [inputText, setInputText] = useState("");
const [items, setItem] = useState([]);

function handleChange(event) {
const newValue = event.target.value;
setInputText(newValue);
}

function addItem() {
setItem((prevItems) => [...prevItems, inputText]);
setInputText("");
}

return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<div className="form">
<input onChange={handleChange} type="text" value={inputText} />
<button onClick={addItem}>
<span>Add</span>
</button>
</div>
<div>
<ul>
{items.map((todoItem) => (
<ToDoItem text={todoItem} />
))}
</ul>
</div>
</div>
);
}

export default App;

 

 

 

 

ToDoItem.js 를 기본형으로 바꿔준다. 

import React from "react";

function ToDoItem(props) {
function handleClick() {}

return (
<div onClick={handleClick}>
<li>{props.text}</li>
</div>
);
}

export default ToDoItem;

 


 

아이템 지우기 

 

아이템을 클릭 했을 때

해당 아이템을 지우려면

로컬 컴포넌트 안에서 해결되는 것이 아니라 

부모 컴포넌트에 있는 array를 건드려야 한다. 

 

어떻게 해야할까?

 

 

 

함수도 props로 통과 시키기 

props 에 value 뿐만 아니라 함수도 같이 통과 시킬 수 있다. 

 

 

App.js의 <ToDoItem /> 태그에 

text property에 더해서 함수 property를 추가해 보자. 

그리고 통과 시킬 함수를 적어준다. 

 

 

 

이 함수를  ToDoItem.js에서 

아이템을 클릭했을 시 함수가 실행되도록 해보자. 

 

 

onClick에다가  앞에서 만든 onChecked 함수를 통과 시켜준다. 

 

 

 

함수가 잘 통과하는지 확인하자. 

deleteItem 함수에 내용을 입력한 후 

App.js

 

 

buy milk 아이템을 클릭하니 

 

 

 

콘솔에 내용이 떴다. 함수가 잘 작동한다. 

 

 

이제는 deleteItem 함수에 

선택된 아이템을 진짜 지우도록 해보자. 

 

그러면 deleteItem에서 아이템을 items array에서 찾아내

해당 아이템을 빼고 array를 다시 정렬하는 방법을 쓴다.

그러면 item array를 다시 설정해야 하니 setItem 함수를 실행한다. 

 

 

어떻게 하면 지워야하는 아이템을 부모 컴포넌트에서 알 수 있을까? 

요청은 자식 태그에 있는 아이템에서 하는데 

deleteItem 함수는 어떻게 많은 아이템 중에 하나를 찾아 낼 수 있을까?

 

 

index, id  필요

이 때 index와  id가 필요하다. 

 

map() 으로 돌릴 때 key, id도 같이 정보를 보낸다.

map() 위에 마우스를 올려보면 들어갈 수 있는 파라미터가 나오는데 

value는 아무거나 되고, index는 숫자라고 나온다. 

 

 

 

map()에 index 파라미터도 추가한다. 

2개 이상일 땐 ()를 해줘야한다. 

 

 

실제로는 index를 key에 사용하지 않는다. 

index는 문자로 되어있기 때문이다.

 

참고 uuid 

https://www.npmjs.com/package/uuid

 

 

지금은 연습으로 index를 쓰고 id도 추가 시킨다.

 

 

 

inspect -> component에 들어가서

각 아이템을 클릭해 보면 

각 key 번호가 나오는 것을 볼 수 있다. 

 

 

id=0인 아이템 

 

 

 

그러면 이제 ToDoItem.js의

onChecked 함수에서 아이템의 id를 불러오면 된다. 

 

하지만 아래와 같이 함수 안에 바로 id를 넣을 수 없다. 

 

함수에 ()가 붙으면 calling function으로 바로 실행이 되어 버린다.

이 함수는 클릭이 되었을 때 실행이 되어야한다. 

 

 

 

그래서 passing function을 해서 클릭이 되었을 때 함수가 실행되도록 한다. 

고로 따로 콜백 함수를 만들어 사용한다. 

 

 

 

 

 

deleteItem 함수 작업

다시  deleteItem 함수로 돌아가서  delete를 실행 시켜보자. 

 

 

 

filter()를 사용해서 deleteItem 함수에 들어온 id를 모든 prevItems array에서 찾는다.

해당 아이템을 빼고 array를 다시 정렬 시킬 것이다.

 

여기서도 filter 함수에 바로 filter(내용)을 넣어버리면 함수가 실행되어 버린다.

그래서 익명함수 형태  filter(()=>{}) 로 넣어준다  

 

 

 

 

filter 함수의 파라미터는 (element, index, array)가 들어갈 수 있다. 

첫번째 파라미터: 실제적으로 array에서 loop을 도는 element

두번째 파라미터: 현 element의 인덱스

 

 

 

filter 함수가 각각 item 들을 하나씩 보면서 

파이널 array는

index가 id와 같지 않은 모든 item들을 리턴을 해준다. 

 

 

 

filter syntax

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

 

 

클릭하면 아이템 지워진다. 

 

 

 

 

 

App.js

import React, { useState } from "react";
import ToDoItem from "./ToDoItem";

function App() {
const [inputText, setInputText] = useState("");
const [items, setItems] = useState([]);

function handleChange(event) {
const newValue = event.target.value;
setInputText(newValue);
}

function addItem() {
setItems((prevItems) => [...prevItems, inputText]);
setInputText("");
}

function deleteItem(id) {
setItems((prevItems) => {
return prevItems.filter((item, index) => {
return index !== id;
});
});
}

return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<div className="form">
<input onChange={handleChange} type="text" value={inputText} />
<button onClick={addItem}>
<span>Add</span>
</button>
</div>
<div>
<ul>
{items.map((todoItem, index) => (
<ToDoItem
key={index}
id={index}
text={todoItem}
onChecked={deleteItem}
/>
))}
</ul>
</div>
</div>
);
}

export default App;

 

ToDoItem.js

import React from "react";

function ToDoItem(props) {
return (
<div
onClick={() => {
props.onChecked(props.id);
}}
>
<li>{props.text}</li>
</div>
);
}

export default ToDoItem;

 

 

댓글