https://github.com/yeonhub/module-assignment
지난번에 vanilla javascript와 module을 사용해서 명단 리스트를 구현해보았다.
이에 몇가지 기능을 추가 해 React로 만들어 보았다.
- 명단 추가
- 명단 초기화
- 명단 개별 삭제
import React, { useRef, useState } from 'react';
import '../assets/css/reset.css'
import './Staff.scss'
import dataList from '../assets/api/StaffData'
import StaffList from './StaffList';
import StaffForm from './StaffForm';
const Staff = () => {
const [data, setData] = useState(dataList)
const no = useRef(dataList.length + 1)
const [isAdd, setIsAdd] = useState(false)
const showAdd = () => {
setIsAdd(!isAdd)
}
const onDel = (id) => {
setData(data.filter(item => item.id !== id))
}
const onDelAll = () => {
setData([]);
}
const onRe = () => {
setData(dataList);
}
const onAdd = (user) =>{
setData(
[
...data,
{id : no.current++,...user}
]
)
}
const onLike =(id)=>{
setData(data.map(item => item.id === id ? { ...item, like: !item.like } : item))
}
return (
<div className='wrap'>
<div className="list">
<h2>직원 명단</h2>
<p>
<button onClick={onDelAll}>전체 삭제</button>
<button onClick={onRe}>초기화</button>
</p>
<button className='add' onClick={showAdd}>명단 추가</button>
{
isAdd && <StaffForm onAdd={onAdd}/>
}
<StaffList data={data} onDel={onDel} onLike={onLike}/>
</div>
</div>
);
};
export default Staff;
1) 명단 추가
import React, { useRef, useState } from 'react';
const StaffForm = ({ onAdd }) => {
const [user, setUser] = useState(
{ name: '', job: '', tel: '', img: '' }
)
const nameRef = useRef(null)
const { name, job, tel, img } = user
const changeInput = e => {
const { name, value } = e.target
setUser({ ...user, [name]: value })
}
const onSubmit = e => {
e.preventDefault();
if (!name || !job || !tel || !img) return
onAdd(user)
setUser({ name: '', job: '', tel: '', img: '' })
nameRef.current.focus();
}
return (
<form onSubmit={onSubmit}>
<p>
<label htmlFor="">이름</label>
<input type="text" name='name' value={name} onChange={changeInput} ref={nameRef} placeholder='이름'/>
</p>
<p>
<label htmlFor="">직업</label>
<input type="text" name='job' value={job} onChange={changeInput} placeholder='직업'/>
</p>
<p>
<label htmlFor="">연락처</label>
<input type="text" name='tel' value={tel} onChange={changeInput} placeholder='010-0000-0000'/>
</p>
<p>
<label htmlFor="">사진</label>
<input type="text" name='img' value={img} onChange={changeInput} placeholder='사진 링크'/>
</p>
<p>
<button>추가</button>
</p>
</form>
);
};
export default StaffForm;
명단 추가는 form 태그와 input 태그를 사용해 구현했다.
onSubmit을 추가해 엔터를 눌렀을 때도 추가되도록 했다.
각각 항목에 맞는 name과 value를 가져와서 user에 담아준다. 그 뒤 onAdd함수에 user를 넣어주면 Staff.js에서 받아 처리가 가능하다.
const onAdd = (user) =>{
setData(
[
...data,
{id : no.current++,...user}
]
)
}
2) 명단 초기화
const onDelAll = () => {
setData([]);
}
명단 초기화는 간단하게 data에 빈 배열을 넣어 만들었다.
3) 명단 개별 삭제
import React from 'react';
const StaffItem = ({ item, onDel, onLike }) => {
const { id, img, name, job, tel, like } = item
return (
<li>
<img src={img} alt={name} />
<div>
<strong>{name}</strong>
<span>{job}</span>
<p>{tel}</p>
</div>
<div>
{
like ? <i className='xi-heart' onClick={() => onLike(id)}></i> : <i className='xi-heart-o' onClick={() => onLike(id)}></i>
}
<button onClick={() => onDel(id)}>퇴사</button>
</div>
</li>
);
};
export default StaffItem;
data 배열을 받아 li로 뿌려주는 컴포넌트에서 삭제 button을 만들 때 onDel함수를 붙여주었다.
부모 컴포넌트에서 id값도 받아왔기 때문에 클릭한 해당 id를 가져올 수 있었다.
const onDel = (id) => {
setData(data.filter(item => item.id !== id))
}
그 후 최상위 컴포넌트에서 filter를 이용해 해당 id와 같지 않은 객체들을 data에 새로 넣어주어 개별 삭제가 가능하도록 했다.