오늘도 코딩하나
[moneybook]_day2 본문
1. update
React 공부를 하면서 update 해보기는 했지만
항목 1~2개만 가지고 간단하게만 해봤었기 때문에 어떻게 해야할지 많이 헤맸다.
const handleBlur = (id, key, event) => {
const newItem = event.target.innerText;
dispatch(updateItem({id, newData: { [key]: newItem } }));
}
return (
{payList.map((item,i) => (
<tr key={i}>
<td><input type="checkbox" checked={checkedItems.includes(item.id)} onChange={() => handleCheck(item.id)} /></td>
<Input onBlur={(e) => handleBlur(item.id, 'date', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.date}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'group1', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.group1}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'group2', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.group2}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'price1', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.price1}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'price2', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.price2}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'payment', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.payment}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'remark', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.remark}</Input>
</tr>
))}
)
id, key, value 값을 넘겨서 update되도록 소스코드를 작성했다.(onBlur)
(이게 최선인지는 아직 잘 모르겠지만..)
reducers : {
updateItem(state, action) {
const { id, newData } = action.payload;
const index = state.findIndex(item => item.id === id);
if(index > -1) {
state[index] = { ...state[index], ...newData };
}
}
}
update reducer는 id값으로 index를 찾고, 해당 index의 데이터를 update시켰다.
*** 번외
onBlur={(e) => handleBlur(item.id, 'date', e)} 이게 너무 중복되어 더 좋은 방법은 없는지 생각하던 중
챗GPT한테 물어봤다.
const fields = [
{ key: 'date', label: '날짜' },
{ key: 'group1', label: '분류' },
{ key: 'group2', label: '항목' },
{ key: 'price1', label: '지출금액' },
{ key: 'price2', label: '실지출금액' },
{ key: 'payment', label: '결제수단' },
{ key: 'remark', label: '비고' }
];
return (
{payList.map((item, i)=> (
<tr key={i}>
{fields.map(field => {
<Input key={field.key} onBlur={()=>handleBlur(item.id, field.key)}>{item[field.key]}</Input>
})}
</tr>
))}
)
이렇게 작성하라고 알려줬는데
좋은 방법 같기도 하지만 우째 더 복잡한거 같기도 하고 해서 일단은 이전 방법으로 진행했다.
2. delete
delete 관련 로직을 짜면서는 체크에 대한 것들로 인해 조금 헤맸다.
const [checkedItems, setCheckedItems] = useState([]);
const [checkedAll, setCheckedAll] = useState(false);
// 체크항목
const handleCheck = (id) => {
setCheckedItems((prev) =>
prev.includes(id) ? prev.filter((itemId) => itemId !== id) : [...prev, id]
)
}
// 전체선택/해제
const handleCheckedAll = () => {
if(checkedAll) {
setCheckedItems([]);
} else {
const allIds = payList.map(item => item.id);
setCheckedItems(allIds);
}
setCheckedAll(!checkedAll);
}
// 전체선택/해제
useEffect(() => {
(checkedItems.length === payList.length && payList.length > 0) ? setCheckedAll(true) : setCheckedAll(false)
}, [checkedItems, payList])
return (
<tbody>
{payList.map((item,i) => (
<tr key={i}>
<td><input type="checkbox" checked={checkedItems.includes(item.id)} onChange={() => handleCheck(item.id)} /></td>
<Input onBlur={(e) => handleBlur(item.id, 'date', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.date}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'group1', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.group1}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'group2', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.group2}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'price1', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.price1}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'price2', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.price2}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'payment', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.payment}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'remark', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.remark}</Input>
</tr>
))}
</tbody>
<Button variant="outline-dark" size="sm" onClick={()=>dispatch(deleteItem(checkedItems))}>선택삭제</Button>
);
항목별 체크박스 체크여부 checkedItems
전체선택/해제 체크여부 checkedAll
3. 입력하면 자동으로 입력란이 추가되며, 새 입력란 어디를 누르든 날짜가 오늘날짜가 입력되도록 세팅
useEffect(() => {
const empty = payList.filter((item) => item.date !== undefined && item.date !== '');
if(empty.length === payList.length) dispatch(addItem());
}, [payList])
const handleDate = (id, dt) => {
const today = new Date();
if(dt === '' || dt === undefined) {
dispatch(updateItem({id, newData: { ['date']: `${today.getFullYear()}-${String(today.getMonth()+1).padStart(2,'0')}-${today.getDate()}` } }));
}
}
return (
{payList.map((item,i) => (
<tr key={i}>
<td><input type="checkbox" checked={checkedItems.includes(item.id)} onChange={() => handleCheck(item.id)} /></td>
<Input onBlur={(e) => handleBlur(item.id, 'date', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.date}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'group1', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.group1}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'group2', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.group2}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'price1', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.price1}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'price2', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.price2}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'payment', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.payment}</Input>
<Input onBlur={(e) => handleBlur(item.id, 'remark', e)} onKeyDown={handleKeyDown} onClick={()=>handleDate(item.id, item.date)}>{item.remark}</Input>
</tr>
))}
)
reducers : {
addItem(state) {
const newItem = {id:state.length};
state.push(newItem);
}
}
(1) useEffect를 활용해서 addItem()함수를 호출하여 입력란 추가
(2) onClick시 handleDate함수를 호출하여 빈입력란을 누르면 오늘 날짜가 입력되게 세팅
*** 번외
useEffect로 addItem()함수를 호출하는 로직을 작성했는데,
빈 입력란이 2개 나오는 현상이 있었다.(초기값이 2개)
→ React.StrictMode를 지워주니 정상 작동했다.
### 여기까지 오기까지 넘나리 헤매고 힘들었다...
반복해서 연습하다보면 실력이 느리라 믿고 오늘의 스터디를 마친다.ㅠㅠㅠ
'React > Daily' 카테고리의 다른 글
[moneybook]_day6 (0) | 2024.09.02 |
---|---|
[moneybook]_day5 (0) | 2024.08.30 |
[moneybook]_day4 (0) | 2024.08.29 |
[moneybook]_day3 (0) | 2024.08.24 |
[moneybook]_day1 (0) | 2024.08.22 |