Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

오늘도 코딩하나

[moneybook]_day2 본문

React/Daily

[moneybook]_day2

오늘도 코딩하나 2024. 8. 24. 00:35

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를 지워주니 정상 작동했다.

 

그러보니 아무리 테스트데이터여도... 2021년이라니... 나 얼마나 과거에 사는것인가...

 

 

### 여기까지 오기까지 넘나리 헤매고 힘들었다...

반복해서 연습하다보면 실력이 느리라 믿고 오늘의 스터디를 마친다.ㅠㅠㅠ

'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