2024. 5. 8. 16:56ㆍ· FRONT-END/└ React
환경 : Visual Studio Code
- Ex03.js
import { useState } from "react";
import Jumbotron from "./Jumbotron";
function Ex03(){
const [items, setItems] = useState(
[
{itemNo:1, itemName:"참이슬", itemPrice:1200},
{itemNo:2, itemName:"처음처럼", itemPrice:1500},
{itemNo:3, itemName:"새로", itemPrice:1700},
{itemNo:4, itemName:"좋은데이", itemPrice:1000},
{itemNo:5, itemName:"청하", itemPrice:2200}
]
);
//전체 삭제란 비어있는 배열로 state를 덮어쓰기 한다는 것을 의미한다
//(중요) React는 절대로 state를 고치면 안 된다(새로 만들어 덮어쓰기 해야 함)
//function clearItems(e) {}
const clearItems = (e) => {
setItems([]);//삭제
};
const deleteItem = (target) => {
//items에서 item이 아닌 항목만 검색해서 재설정(삭제 효과)
// const searchItems = items.filter(function(item){
// return item.itemNo !== target.itemNo;
// });
const searchItems =
items.filter((item)=>item.itemNo !== target.itemNo);
setItems(searchItems);//검색 결과로 state를 덮어쓰기
};
return(
<>
<Jumbotron title="예제3번" content="예제 3번일까나?"></Jumbotron>
<div className="row mt-4">
<div className="col">
{/* <button className="btn btn-danger" onClick={clearItems}>전체삭제</button> */}
<button className="btn btn-danger" onClick={e => clearItems(e)}>전체삭제</button>
</div>
</div>
<div className="row mt-4">
<div className="col">
<table className="table table-hover text-center">
<thead>
<tr>
<td>번호</td>
<td>품명</td>
<td>가격</td>
<td>삭제</td>
</tr>
</thead>
<tbody>
{/*
map을 이용한 반복을 할 때
생성하는 태그에 제어가 가능한 고유 식별자를 추가(key)
안해도 구동은 되지만 지속적인 오류 + 순서 변환 안 됨
*/}
{items.map((item) => (
<tr key={item.itemNo}>
<td>{item.itemNo}</td>
<td>{item.itemName}</td>
<td>{item.itemPrice}원</td>
<td>
<button className="btn btn-danger" onClick={e=>deleteItem(item)}> − </button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</>
);
}
export default Ex03;
(+) 리액트에서 삭제를 진행할 때 state를 고치는 것이 아니라 새로 만들어 덮어쓰기하는 방식으로 진행해야 한다.
(+) 전체 항목 삭제는 아래와 같은 코드로 진행된다.
//전체 삭제란 비어있는 배열로 state를 덮어쓰기 한다는 것을 의미한다
//(중요) React는 절대로 state를 고치면 안 된다(새로 만들어 덮어쓰기 해야 함)
//function clearItems(e) {}
const clearItems = (e) => {
setItems([]);//삭제
};
(+) state를 빈 배열로 덮어씌워주는 효과


- 삭제한 것과 같은 효과
- 새로고침하면 다시 돌아온다
(+) 개별 항목 삭제는 아래와 같은 코드로 진행된다.
const deleteItem = (target) => {
//items에서 item이 아닌 항목만 검색해서 재설정(삭제 효과)
// const searchItems = items.filter(function(item){
// return item.itemNo !== target.itemNo;
// });
const searchItems =
items.filter((item)=>item.itemNo !== target.itemNo);
setItems(searchItems);//검색 결과로 state를 덮어쓰기
};
(+) 주석의 코드를 줄여 쓴 코드이다.
(+) 삭제버튼을 누른 아이템의 번호와 아이템 배열에 있는 아이템 번호가 같지 않은 아이템들만 남길 수 있도록 filer메소를 사용한다.

(+) 전체 삭제의 경우 간단히 함수 이름만으로도 호출 가능하다 (주석 참고)
{/* <button className="btn btn-danger" onClick={clearItems}>전체삭제</button> */}
<button className="btn btn-danger" onClick={e => clearItems(e)}>전체삭제</button>
(+) 현재 타깃이 된 아이템의 정보를 넘겨주기 위해서 onClick 함수에 화살표함수를 넣어준다 (e=>deleteItem(item))
각종 오류를 막기 위해 한 번 <tr> 태그가 돌 때마다 어떤 아이템인지 정보를 알 수 있도록 key 값을 설정해준다.
{/*
map을 이용한 반복을 할 때
생성하는 태그에 제어가 가능한 고유 식별자를 추가(key)
안해도 구동은 되지만 지속적인 오류 + 순서 변환 안 됨
*/}
{items.map((item) => (
<tr key={item.itemNo}>
<td>{item.itemNo}</td>
<td>{item.itemName}</td>
<td>{item.itemPrice}원</td>
<td>
<button className="btn btn-danger" onClick={e=>deleteItem(item)}> − </button>
</td>
</tr>
))}
이번엔 위의 예제와 비슷하지만 안티 테이블 형식으로 코딩하고, 함수를 더 명확하게 사용해겠다
- Ex04.js
import { useCallback, useState } from "react";
import Jumbotron from "./Jumbotron";
function Ex04() {
//state
const [nations, setNations] = useState([
{no:1, name:"한국", capital:"서울"},
{no:2, name:"미국", capital:"워싱턴"},
{no:3, name:"일본", capital:"도쿄"},
{no:4, name:"중국", capital:"베이징"},
{no:5, name:"영국", capital:"런던"},
{no:6, name:"프랑스", capital:"파리"},
{no:7, name:"독일", capital:"베를린"},
{no:8, name:"인도", capital:"뉴델리"},
{no:9, name:"호주", capital:"캔버라"},
{no:10, name:"스페인", capital:"마드리드"},
]);
//function(callback)
// - const 함수명 = useCallback(함수, [연관항목]);
// - 연관항목이 변했을 경우만 함수를 재설정하게 되어 최적화 가능
// - 연관항목이 없으면 비어있는 배열로 설정
//function deleteNation(target){}
//const deleteNation = (target)=>{}; 화살표 함수(arrow function)사용 (this 사용을 막기 위해)
const deleteNation = useCallback((target)=>{
const searchResult = nations.filter((nation)=>nation.no !== target.no);
setNations(searchResult);
}, [nations]);
const clearNations = useCallback(()=>{
setNations([]);
}, [nations]);
return (
<>
<Jumbotron title="국가 정보" content="목록, 전체삭제, 삭제까지 구현"/>
<div className="row mt-4">
<div className="col text-end">
<button className="btn btn-danger"
onClick={e=>clearNations()}>전체삭제</button>
</div>
</div>
<div className="row mt-4 text-center">
<div className="col-3">번호</div>
<div className="col-3">국가</div>
<div className="col-3">수도</div>
<div className="col-3">메뉴</div>
</div>
<hr/>
{nations.map((nation)=>(
<div className="row mt-2 text-center align-items-center" key={nation.no}>
<div className="col-3">{nation.no}</div>
<div className="col-3">{nation.name}</div>
<div className="col-3">{nation.capital}</div>
<div className="col-3">
<button className="btn btn-danger"
onClick={e=>deleteNation(nation)}>삭제</button>
</div>
</div>
))}
</>
);
}
export default Ex04;
(+) const 함수명 = useCallback(함수, [연관항목]);
- 연관항목이 변했을 경우만 함수 재설정하게 되어 최적화 가능
- 연관항목이 없으면 비어있는 배열로 설정
const deleteNation = useCallback((target)=>{
const searchResult = nations.filter((nation)=>nation.no !== target.no);
setNations(searchResult);
}, [nations]);
const clearNations = useCallback(()=>{
setNations([]);
}, [nations]);
(+) div 태그로 테이블 느낌 냄
(+) 글씨를 div태그 중앙에 올 수 있도록 align-items-center를 사용
<div className="row mt-2 text-center align-items-center" key={nation.no}>

개인 공부 기록용입니다:)
'· FRONT-END > └ React' 카테고리의 다른 글
[ React ] 아.추하기 (아이콘 추가하기라는 뜻) (0) | 2024.05.11 |
---|---|
[ JavaScript / React ] 등록/조회/삭제 해보기 (0) | 2024.05.09 |
[ JavaScript / React ] js, bootswatch 메뉴바 디자인 적용 및 map() 함수 사용 (0) | 2024.05.06 |
[ JavaScript / React ] 리액트 연습 (0) | 2024.05.02 |
[React] 기본 컴포넌트 배치 (0) | 2024.05.01 |