- 추가, 삭제, 수정
- useRef
1) 추가, 삭제, 수정
import React, { useState } from 'react';
const dataList = [
{ id: 1, name: '김' },
{ id: 2, name: '이' },
{ id: 3, name: '박' },
{ id: 4, name: '최' },
{ id: 5, name: '정' }
]
const Test2 = () => {
const [data, setData] = useState(dataList)
const onDel1 = () => {
setData(data.filter(item => item.name !== '김'))
}
const onDel2 = () => {
setData(data.filter(item => item.name !== '이'))
}
const onDel3 = () => {
setData(data.filter(item => item.name !== '박'))
}
const onDel = (id) => {
setData(data.filter(item => item.id !== id))
}
const onAdd1 = () => {
setData([
...data,
{
id: data.length + 1,
name: '윤'
}
])
}
const onAdd2 = () => {
setData([
...data,
{
id: data.length + 1,
name: '소'
}
])
}
const onAdd3 = () => {
setData([
...data,
{
id: data.length + 1,
name: '진'
}
])
}
const onAdd = (name) => {
setData([
...data,
{
id: data.length + 1,
name: name
}
])
}
const onMod1 = () => {
setData(data.map(item => {
if (item.id === 3) {
return { ...item, name: '황' }
} else {
return item
}
}))
}
const onMod2 = () => {
setData(data.map(item => item.id === 4 ? { ...item, name: '조' } : item))
}
const onMod = (id) => {
const newData = data.map(item => item.id === id ? { ...item, name: '양' } : item)
setData(newData)
}
return (
<div>
<h2>추가 , 삭제 , 수정</h2>
<p>
<button onClick={onDel1}>김 삭제</button>
<button onClick={onDel2}>이 삭제</button>
<button onClick={onDel3}>박 삭제</button>
<button onClick={() => onDel(4)}>최 삭제</button>
<button onClick={() => onDel(5)}>정 삭제</button>
</p>
<p>
<button onClick={onAdd1}>윤 추가</button>
<button onClick={onAdd2}>소 추가</button>
<button onClick={onAdd3}>진 추가</button>
<button onClick={() => onAdd('반')}>반 추가</button>
<button onClick={() => onAdd('추')}>추 추가</button>
</p>
<p>
<button onClick={onMod1}>수정</button>
<button onClick={onMod2}>수정</button>
<button onClick={() => onMod(5)}>수정</button>
</p>
<ul>
{data.map(item => <li key={item.id}>{item.id} / {item.name}</li>)}
</ul>
</div>
);
};
export default Test2;
<ul>
{data.map(item => <li key={item.id}>{item.id} / {item.name}</li>)}
</ul>
dataList에 있는 객체들의 id와 name을 가져와 li에 담고 출력해 준다.
삭제 버튼을 두 가지 방법으로 구현했는데, 첫 번째는 각각 함수를 만들어 삭제하는 것이다.
const onDel1 = () => {
setData(data.filter(item => item.name !== '김'))
}
const onDel2 = () => {
setData(data.filter(item => item.name !== '이'))
}
const onDel3 = () => {
setData(data.filter(item => item.name !== '박'))
}
두 번째 방법으로 onDel 함수를 호출할 때 매개변수로 삭제하고자 하는 객체의 id값을 지정하는 것이다.
<button onClick={() => onDel(4)}>최 삭제</button>
<button onClick={() => onDel(5)}>정 삭제</button>
const onDel = (id) => {
setData(data.filter(item => item.id !== id))
}
이렇게 하면 filter로 dataList id와 해당 id가 같지 않은 객체만 남겨 다시 dataList에 담게 된다.
추가의 경우도 마찬가지로 두 가지 방법으로 구현했는데 방식은 제거와 비슷하다.
const onAdd3 = () => {
setData([
...data,
{
id: data.length + 1,
name: '진'
}
])
}
const onAdd = (name) => {
setData([
...data,
{
id: data.length + 1,
name: name
}
])
}
대신에 기존에 남아있는 data들을 지우면 안되므로 ...data를 맨 앞에 넣어 추가하는 방식으로 했다.
const onMod1 = () => {
setData(data.map(item => {
if (item.id === 3) {
return { ...item, name: '황' }
} else {
return item
}
}))
}
const onMod2 = () => {
setData(data.map(item => item.id === 4 ? { ...item, name: '조' } : item))
}
const onMod = (id) => {
const newData = data.map(item => item.id === id ? { ...item, name: '양' } : item)
setData(newData)
}
수정의 경우 if를 사용해 return 시키는 방법과, 삼항연산자를 사용하는 방법으로 구현했다.
onMod2와 onMod의 차이점은 map으로 생성된 배열 선언 유무이다.
2) useRef
useRef를 사용해야 하는 경우 중 고유번호를 지정할 때가 있다.
예를 들어 배열에 새로운 객체가 추가될 때 식별할 수 있는 id값을 컴포넌트 내에서 사용할 수 있는 변수를 써야 한다.
import React, { useRef, useState } from 'react';
const Test5 = () => {
const [data, setData] = useState([])
const no = useRef(1)
const names = '김,이,박,최,정,민,송,전,임,하'.split(',')
const onAdd = () => {
const ran = Math.floor(Math.random() * names.length)
setData([
...data,
{
id : no.current ++,
text : names[ran]
}
])
}
return (
<div>
<button onClick={onAdd}>추가</button>
<ul>
{
data.map(item => <li key={data.id}>{item.id} / {item.text}</li>)
}
</ul>
</div>
);
};
export default Test5;
두 번째는 특정 컴포넌트에 focus 해야 할 때이다.
이름과 나이를 입력하고 추가 버튼을 눌렀을 때 입력한 값들은 배열에 저장되어 출력되고 input엔 입력한 value들이 삭제되고 이름 input에 focus가 되어야 한다면, 이름 input에 useRef를 사용해야 한다.
import React, { useRef, useState } from 'react';
const Test6 = () => {
const textRef = useRef(null)
const no = useRef(1)
const [data, setData] = useState([])
const [user, setUser] = useState({
text: '',
age: ''
})
const { text, age } = user
const changeInput = (e) => {
const { name, value } = e.target
setUser({
...user,
[name]: value
})
}
const onAdd = () => {
setData([
...data,
{
id: no.current++,
text: text,
age: age
}
])
textRef.current.focus()
}
const onDel = (id) => {
setData(data.filter(item => item.id !== id))
}
return (
<div style={{ margin: 30 }}>
<p>
<input type="text" placeholder='이름' value={text} name='text' onChange={changeInput} ref={textRef} />
<input type="text" placeholder='나이' value={age} name='age' onChange={changeInput} />
<button onClick={onAdd}>추가</button>
</p>
<ul>
{
data.map(item => <li key={item.id}>{item.id} / {item.text} / {item.age}<button onClick={()=>onDel(item.id)}>삭제</button></li>)
}
</ul>
</div>
);
};
export default Test6;