모달 창을 하려고 했는데, 그전에 버그 수정
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: 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