전화번호부의 특정 아이템을 삭제하는 함수를 만들어봅시다.
이번 장에서는 전화번호부 아이템을 삭제하는 handleRemove 함수를 만들어보겠습니다. 먼저 App 컴포넌트를 아래와 같이 수정해주세요.
import React, { Component } from "react";
import InputBox from "./components/InputBox";
import PhoneList from "./components/PhoneList";
import "./App.css";
import { dummyData, nextId, setNextId } from "./lib/dummyData.js";
class App extends Component {
state = {
dummyData,
name: "",
phone: ""
};
handleInput = e => {
this.setState({
[e.target.name]: e.target.value
});
};
handleSubmit = () => {
const { dummyData, name, phone } = this.state;
if (name === "" || phone === "") return;
this.setState({
dummyData: {
...dummyData,
[nextId]: {
id: String(nextId),
name,
phone
}
},
name: "",
phone: ""
});
setNextId();
};
handleRemove = id => {
const { [id]: _, ...dummyData } = this.state.dummyData;
this.setState({ dummyData });
};
render() {
const { handleInput, handleSubmit, handleRemove } = this;
const { dummyData, name, phone } = this.state;
return (
<div className="container">
<InputBox
name={name}
phone={phone}
onChange={handleInput}
onSubmit={handleSubmit}
/>
<PhoneList list={dummyData} deleteItem={handleRemove} />
</div>
);
}
}
export default App;
그럼 이제 handleRemove 함수 코드를 봅시다. handleRemove 함수의 맨 윗줄은 Destructing Assignment, Spread 문법을 모두 사용해서 처음엔 보기 어려울 수 있습니다. 저 코드를 해석해봅시다. 먼저 "[id]: _" 를 통해 제거하고 싶은 아이템을 _라는 변수에 할당합니다. 그리고 Spread 문법을 통해 앞에서 제외한 아이템을 뺀 데이터를 dummyData에 저장합니다. 그런 다음, setState 함수에 dummyData를 넘겨주면 불변성을 위반하지 않고 올바르게 데이터를 변경할 수 있습니다. 이 함수는 PhoneList 컴포넌트에 deleteItem이라는 Props로 전달했으므로 PhoneList 컴포넌트를 수정해봅시다.
import React from "react";
import PhoneItem from "../PhoneItem";
import styled from "styled-components";
const PhoneWrapper = styled.div`
display: flex;
flex-direction: column;
padding-bottom: 50px;
`;
const PhoneList = ({ list, deleteItem }) => {
return (
<PhoneWrapper>
{Object.values(list).map(item => {
return <PhoneItem {...item} key={item.id} onClick={deleteItem} />;
})}
</PhoneWrapper>
);
};
export default PhoneList;
PhoneList에서 Props를 받고 다시 PhoneItem 컴포넌트에 onClick이라는 Props를 전달해주었습니다. 그럼 이제 PhoneItem 컴포넌트를 수정해보겠습니다.
import React from "react";
import styles from "./PhoneItem.module.scss";
const PhoneItem = ({ id, name, phone, onClick }) => {
return (
<div className={styles.phone_item}>
<div className={styles.phone_item_left}>
<div className={styles.phone_item_name}>{name}</div>
<div className={styles.phone_item_phone}>{phone}</div>
</div>
<div className={styles.phone_item_right}>
<button onClick={() => onClick(id)}>삭제</button>
</div>
</div>
);
};
export default PhoneItem;
위와 같이 PhoneItem 컴포넌트의 Button onClick 이벤트 핸들러로 Props로 전달받은 onClick 함수를 지정했습니다. 다만 여기서 "onClick={onClick(id)}"라고 적지 않은 이유는 React에서 이런 이벤트 핸들러로 함수 레퍼런스, 즉 함수 그 자체를 전달해야 하기 때문입니다. 따라서 onClick과 같은 이벤트 속성에 핸들러를 전달할 때에는 "onClick={onClick}"과 같이 소괄호를 제외하고 보냅니다. 다만 여기서는 onClick 함수가 id 파라미터를 받기 때문에 Arrow Function으로 새 함수를 만들고 이를 전달해주는 것입니다.