연습장

[Todo list] 07. update ,delete 버그 수정 본문

클론코딩해보기/TodoList

[Todo list] 07. update ,delete 버그 수정

js0616 2024. 8. 20. 07:04

모달 창을 하려고 했는데,  그전에 버그 수정

 

items 에 들어가야할 item 들이 this.state 에 바로 저장되고 있는것을 확인

    this.addEvent('click', '.updateBtn', () => {
      item.write = true;
      updateItem(item);
      inputFocus(`[data-Item${item.seq}] .upTitle`);
    });

    this.addEvent('change', '.workState', e => {
      item.workState = e.target.value;
      updateItem(item);
      setWorkCount();
    });

 

updateItem 이 문제가 있는듯 하다.

 

기존

    this.setState( items );

 

수정

    this.setState({ items: items });

 

 

하고보니까.. 

 

update 기능이 이상한거 같아서 수정

-> 기존의 update 는 객체를 새로 만들어서 그걸 넣는방식으로 하려고했었는데 

-> seq, 키 , 새로운 값을 받아서 직접 변경하는 식으로 하는게 더 간단해보임. 

-> 안됨 , component 가 객체 형태로 넣도록 구성되어있음.. 

->  this.setState({ items: items }); 와 같은 느낌으로 해야됨

 


-> delete 의 경우도 state 가 더미 데이터가 입력됨.. 

-> 임시 배열을 만들고 이를 state 에 저장하는 방식으로 하려고 보니 

-> 코드를 수정하다 보니

임시배열의 경우 splice 위치에 관계없이

삭제 된 값이 console.log 로 바로 보여지는것 같음... 이건 js 의 뭐 그런 특성 아닐까 

  deleteItem(itemSeq) {
    // itemSeq : Item.seq 를 받아온다.
    let items = [...this.state.items];
    console.log('삭제전:', items);
    let seqArray = this.state.items.map(item => item.seq);
    let delIndex = seqArray.findIndex(item => item == itemSeq);

    items.splice(delIndex, 1);
    console.log('삭제후:', items);
    console.log('state 전 :', this.state);
    this.setState({ items: items });
    console.log('state 후:', this.state);
  }

 

 

펼치기 전에는 3개(삭제전), 2개(삭제후) 로 올바른 것 처럼 보이는데, 

 

 

이를 펼쳐서 세부 내용을 확인하면, 지역변수(임시배열) items 의 값이 이미 사라진것이 확인됨...

state 는 이상 없으니까 일단 진행. 


다시 update 로 돌아와서 delete 처럼 해보려고 했으나.. 

  updateItem(seq, key, val) {
    let items = [...this.state.items];
    let seqArray = items.map(item => item.seq);
    let updateIndex = seqArray.findIndex(item => item == seq);

    console.log('임시 수정전', items);
    items[updateIndex][key] = val;
    console.log('임시 수정후', items);
    console.log('state 변경 전', this.state);
    // this.setState({items : ~~ })
  }

 

이 경우는 임시배열 수정전 /  후 / state 변경 모두 한번에 일어남 -> 아마 pass by reference  인것 같은데 

setState 만 state 를 변경하도록 코드를 작성하고 싶기 때문에..

 

방법1. 삭제하고 추가해서 update 인척하기 

방법2. 깊은 복사 하기  [ JSON.parse 방법 / structuredClone 사용 / 직접 함수 만들기 / ...  ]

 

structuredClone  문법을 사용하기로 함

 

다음과 같이 items 라는 지역변수의 임시 배열은 delete 와 마찬가지로 수정 전이든 후든 수정된 상태로 표기 되지만

state 는 false 로  pass by reference 에서 벗어나서 서로 다른곳을 참조를 하는것을 알 수 있음. 

 

 

 

 

  // 수정하기
  updateItem(seq, key, val) {
    let items = structuredClone(this.state.items);
    let seqArray = items.map(item => item.seq);
    let updateIndex = seqArray.findIndex(item => item == seq);
    items[updateIndex][key] = val;
    this.setState({ items: items });
  }

 

그리고 해당 함수 updateItem 을 사용하는 곳을 모두 수정 하다보니까 

한번에 state 를 1개만 바꿀수 있다는것을 알게되었고... 이를 다시 고치기 위해서 

{ key : val } 를 묶은 객체를 전달받고 이를 for 문으로 반복하여 수정하도록 함. 

  /** seq, {'key', NewVal} */
  updateItem(seq, NewItem) {
    let items = structuredClone(this.state.items);
    let seqArray = items.map(item => item.seq);
    let updateIndex = seqArray.findIndex(item => item == seq);

    for (let key in NewItem) {
      items[updateIndex][key] = NewItem[key];
    }
    this.setState({ items: items });
  }

 

모달 창 만들려고 했는데... 이게 무슨일이야... 

 

https://github.com/js0616/todoList

'클론코딩해보기 > TodoList' 카테고리의 다른 글

[Todo list] 09. scss 입히기  (0) 2024.08.23
[Todo list] 08. 모달 창  (0) 2024.08.20
[Todo list] 06. 삭제, 정렬  (0) 2024.08.19
[Todo list] 05. 필터 기능  (0) 2024.08.19
[Todo list] 04. 수정 기능  (0) 2024.08.18