본문 바로가기

Web

JS - list, 배열 요소 삭제 시 새로고침 없이 id 갱신하기

오늘도 노마드 코더의 모멘텀 클론코딩 중 개선한 것을 기록해 본다.

오늘 내가 한 것은 삭제 후 중복되는 id 문제 해결이다.

먼저 이게 어떤 문제인지 캡처와 함께 살펴보자.

task1~4까지 순서대로 삽입했을때 toDos의 모습 확인.

task2를 삭제한 경우 toDos의 모습.

그 후 task5를 삽입하면 task4와 task5의 id가 둘 다 4로 겹치는 것을 알 수 있다.

html또한 li의 id가 1, 3, 4, 4로 중복되고 있다.

새로고침만 해 줘도 id가 1, 2, 3, 4..깔끔하게 정리되지만 중복이 발생하는 건 찝찝하다고 생각하던중

찝찝할 수 밖에 없는, 중복으로 인해 발생할 수 있는 문제를 알게 됐다.

같은 id를 가진 todo를 삭제한 경우 html을 봤을때는 아무 문제가 없지만 local storage는 두 개의 todo모두를 삭제하고 있다.

삭제하는 부분의 js코드는 아래와 같다.

function handleDeleteToDo(event) {
  const btn = event.target;
  const li = btn.parentNode;
  toDoList.removeChild(li);
  const cleanToDos = toDos.filter(function(toDo){
    return toDo.id !== parseInt(li.id);
  });
  toDos = cleanToDos;
  saveToDos();
}

filter를 수행하면서 자신의 id가 삭제한 li의 id (버튼을 자식으로 가지고 있는 li element의 id)와 같은 toDo를 걸러내는데

위의 gif의 경우 task4에 해당하는 li의 id는 4였고, 따라서 id가 4인 두 개의 todo가 삭제된 것이다.

이를 해결하려면 

좌, task2 삭제 전 우, task2 삭제 후

task2를 삭제하고 난 후 task1, task3, task4에 해당하는 list의 id와 localstorage의 id 모두 1, 2, 3이 되도록 코드를 고칠 필요가 있다.

그냥 꼼수를 부리자면 handleDeleteToDo()의 제일 끝에 reload를 호출해서 새로고침 하면 아~주 간단히 해결할 수 있긴 한데... 마음에 안 든다. 새로고침을 안 하고 해결하고 싶다!

그래서 나는.. 이런 함수를 만들었다.

function updateId(removedId) {
  if (toDos.length < removedId) {
    // 목록의 마지막 todo를 삭제한 경우 아무것도 하지 않음
    return;
  } else {
    let newId = parseInt(removedId); // 삭제한 todo의 id를 숫자로 변환하여 newId에 받아온다
    for (let i = removedId - 1; i < toDos.length; i++) { // 삭제한 todo 뒤의(아래의) todo들을 방문하면서 id를 업데이트한다
      toDos[i].id = newId; // 배열에 저장된 객체의 id 업데이트
      toDoList.children[i].id = newId++; // 리스트 엘레먼트의 id 속성 업데이트
    }
  }
}

그리고 handleDeleteToDo(event)의   toDos = cleanToDos;와 saveToDos();사이에서 updateId(li.id)를 호출하도록했다.

새로고침 없이 무결성이 잘 유지되고 있다.

'Web' 카테고리의 다른 글

FE - 모멘텀 페이지 개선 기록  (0) 2021.05.10
JS - input.focus 가 안 되었던 이유  (0) 2021.05.04