[Vanilla JS] TODOLIST (2) - END

하유민·2021년 8월 11일
0

📋 Vanilla JS Projects

목록 보기
2/3
post-thumbnail

🟢 구현된 기능 LIST

  • to-do List 추가, 삭제 기능
  • to-do 가 만들어진 시간 기록
  • 애니메이션 효과

🟡 구현할 기능 LIST

  • to-do List LocalStorage 저장
  • 화면 출력시 정렬

to-do list 는 나갔다가 들어와도, 또는 새로고침을 해도 원래 내용이 그대로 유지되어야 하기 때문에, LocalStorageto-do list 를 통째로 저장해 내용이 유지되도록 만들어볼 계획이다.

까짓거 한 번 해보겠다 .. !

뭔가 도전할 때 항상 생각나는 짤

❓ LocalStorage

  • 데이터를 로컬에 저장한다.
  • 데이터 저장, 삭제 등 javascript 로 조작하여 사용 가능하다.
  • 유효기간이 없다.
  • key value 한 쌍으로 저장된다.

저번 오랑우톡 개발할 때 쿠키를 써보았는데, 쿠키와 사용법이 비슷하면서도.. 좀 달라서 찾아보면서 써보았다.

1) LocalStorage 저장, Todo 생성

// localStorage 객체 형태로 저장
const obj = {'keyValue':keyValue,'text':text, 'time':nowTime};
localStorage.setItem(text, JSON.stringify(obj));
// localStorage 객체 불러오기 
const localObj = JSON.parse(localStorage.getItem(text));
// todo div 만들기
makeTodo(localObj);
// 스크롤 맨 아래로 고정
mainDiv.scrollTop = mainDiv.scrollHeight;
// input 값 초기화 
inputValue.value = '';
  • 먼저 obj 라는 이름의 객체 하나를 만든다. 이 객체 안에는 keyValue, text, time 이 세 개의 key와 value 값이 들어간다.

  • 방금 저장한 로컬스토리지 객체를 text 값으로 불러와 Todo 를 만드는 함수인 makeTodo 에 인자로 보내 todo 한 블록을 만들게 한다.

❗ 이때 유의해야할 점은 value 로는 무조건 string 밖에 저장이 안 되기 때문에 object(객체) -> string(문자열) 으로 변환을 해주어야 한다.

2) LocalStorage 삭제

const del = () => {
    // todo 의 부모를 찾아서 todo 를 삭제 
    const div = event.target.parentNode
    mainDiv.removeChild(event.target.parentNode);
    // localStorage key 값에 해당하는 text에 접근 
    const key = div.childNodes[0].childNodes[0].innerHTML;
    localStorage.removeItem(key);
}
  • del 함수 뒷 부분에 삭제할 값을 key(text 내용)로 찾아 로컬스토리지에서 remove 해주는 코드를 추가해주었다.

3) LocalStorage 출력

❗ 로컬스토리지는 단순 저장밖에 되지 않는다. 즉, 순서는 상관 없이 저장된다.

실제로 리스트를 저장하고 개발자도구로 저장된 값을 확인해보면

1,2,3,4,5 순으로 저장했음에도 불구하고 순서가 뒤죽박죽인 것을 확인할 수 있다.

나는 추가한 순서대로 화면에 출력하고 싶기 때문에, 객체를 생성할 때 넣어준 keyValue 로 로컬스토리지의 객체들을 정렬시킨후, 화면에 출력해줄 것이다.

const list = () => {
    // localStorage key 값으로 list 를 만드는 과정 
    for(let i=0; i<localStorage.length; i++) {
        const localObj = JSON.parse(localStorage.getItem(localStorage.key(i)))
        sortList.push(localObj);
    }
  
    // sortList 정렬 후 출력 
    for (let item=0; item<sortList.length; item++){
        keyList.push(sortList[item].keyValue);
    }
  
    // 정렬 
    keyList.sort();
  
    // 정렬된 key 로 맞는 value 찾고, 새로운 리스트
    //sortedList 에 순서대로 저장.
    for (let i=0; i<keyList.length; i++) {
        for (let j=0; j<sortList.length; j++) {
            if (sortList[j].keyValue === keyList[i]) {
                sortedList.push(sortList[j]);
            } else {
                continue
            }
        }
    }
  
    // 중복제거
    const norepeatList = Array.from(new Set(sortedList));
  
    // 정렬된 리스트로 List 출력 
    for (let i=0; i<norepeatList.length; i++) {
        makeTodo(norepeatList[i]);
    }
}
 

위의 코드는 크게 세 단계로 구성되어있다.

1. keyValue List 저장

LocalStorage 에서 keyValue 값을 for 문으로 하나씩 꺼내와 list 에 저장한다.

2. List 정렬

keyValue 가 저장된 listsort 로 정렬해준 후 정렬된 list 를 for 문을 다시 돌려 keyValue 에 해당하는 객체를 찾아 다시 새로운 list 에 저장해준다.

❕ 여기까지 함으로써 정렬된 keyValue(1,2,3 ...) 의 순서대로 LocalStorage 객체들이 list 에 저장되었다.

3. 정렬된 리스트로 화면에 출력

정렬된 객체들이 저장된 list 를 for문으로 화면에 출력해준다.

🔴 Trouble Shooting 1

위의 움짤을 보면 알 수 있듯이, 새로고침시에는 정렬이 잘 되지만 (원래는 순서가 전부 뒤바뀌어야한다.)

특정 to-do 를 삭제 후 새로운 to-do 를 생성하고 다시 새로고침 하면 순서가 뒤바뀐다. 이 부분에서 애를 정말 많이 먹어서 다양한 방법을 시도해보았다.

시도 1

// 정렬 
    if (localStorage.length > 0){
        keyValue = localStorage.length+1
        let maxNum = 0;
        // max 구할 수 없는 경우
        if (keyList.length === 1) {
            maxNum = keyList.length;
        } else {
            maxNum = (Math.max.apply(null, keyList))+1;
        }
    } else {
        keyValue += 1
    }

LocalStorage 에 아무값도 없을 경우에 keyValue 의 최대값을 찾아 새로 to-do 를 추가할시 keyValue 값을 최대값에서 1 더해준 값으로 저장하는 코드를 짰다. 생각해보니 keyValue 값을 maxNum 으로 지정을 안 해주어서 이 코드는 당연히 안 되는 것이였다 ^-^

시도 2)

// 정렬 
    if (localStorage.length > 0){
        // max 구할 수 없는 경우
        if (localStorage.length === 1) {
            maxNum = sortedKey.length +1;
            keyValue = maxNum;
        } else {
            maxNum = (Math.max.apply(null, sortedKey))+1;
            keyValue = maxNum;
        }
    } else {
        keyValue += 1
    }

그래서 같은 방식으로 다시 짰다.

이래도 안 됐다.

몇 시간을 잡고 해봐도 도저히 안 고쳐졌다...

며칠 뒤에 다시 보면 뭔가 생각이 나지 않을까 싶어 여기까지 해두었다가 오늘 오랜만에 다시 해보았는데, 문제를 찾아버렸다 !

문제는.. sortedKey !

sortedKey 가 전역적으로 선언된 list 가 아닌, 화면에 출력하는 함수 내에서 선언된 list 여서 항상 빈 리스트로 나왔던 문제였다.

그래서 todo 를 만드는 함수에도 다시 sortedKey를 만들어주었다.

시도 3)

const toDo = () => {
    const normalList = [];
    const sortedKey = [];

    const nowTime = makeTime()
    for(let i=0; i<localStorage.length; i++) {
        const localObj = JSON.parse(localStorage.getItem(localStorage.key(i)))
        normalList.push(localObj);
    }
    // sortList 정렬 후 출력 
    for (let item=0; item<normalList.length; item++){
        sortedKey.push(normalList[item].keyValue);
    }
    // 정렬 
    sortedKey.sort();
    // input 에 들어온 text 설정
    let text = inputValue.value;
    let maxNum = 0;
    // 정렬 
    if (localStorage.length > 0){
        // max 구할 수 없는 경우
        if (localStorage.length === 1) {
            maxNum = sortedKey.length +1;
            keyValue = maxNum
        } else {
            maxNum = (Math.max.apply(null, sortedKey))+1;
            keyValue = maxNum;
        }
    } else {
        keyValue += 1
    }

이렇게 맨 첫부분에 sorted list 를 다시 한 번 선언해주었다.

🔴 Trouble Shooting 2

특정 상황에서 순서가 다시 뒤바뀌는 문제가 발생했다. 다행히 원인을 바로 알 수 있었다.

시도 4)

if (localStorage.length === 1) {
            maxNum = sortedKey.length +1;
            keyValue = maxNum

바로 이 부분이다. 남은 todo list 길이가 1일시 새로 to-do 를 추가하면 무조건 maxNum 이 2가 되어버려 순서가 뒤바뀌었다.

그래서 코드를 이렇게 fix !

if (localStorage.length === 1) {
            maxNum = sortedKey[0] + 1;
            keyValue = maxNum

길이가 1이라는 것은 어차피 list요소가 하나라는 뜻이므로, index 0 을 찾아 이 요소의 keyValue 보다 하나 더 큰 값으로 새롭게 생길 to-do 의 keyValue 값을 지정해주었다.

✅ 성공

새로고침 & 중간에 요소 삭제 및 추가를 해도 순서대로 정렬 된다.

✔ 개선할점

  • 지금 생각하니 반복되는 부분은 따로 함수로 만들어 모듈화 했으면 좋았을 것 같다.
  • 수정 기능은 넣지 않았는데, 수정 기능도 넣었으면 좋았을 것 같다.
  • 변수명을 난해하게 지은 것 같다. 한 눈에 봐도 이 변수가 어떤 걸 뜻하는지 지었으면 좋았을 것 같다.
  • 더 간결하고 가독성 있게 코드를 작성하면 좋을 것 같다.

✔ 느낀점

  • TODO LIST 를 만들면서 기본기를 다진 것 같아 기분이 아주 좋다.
  • Trouble Shooting 과정에서 많이 헤맨 것 같은데, 결국 모든 Bug 를 해결해서 뿌듯했다.
  • 이 프로젝트를 하면서 JS 에 자신감도 붙고, 더 많이 알게된 것 같아 행복했다.
  • 알아감으로써 얻는 기분 좋음을 많이 느꼈던 프로젝트였다.

역시 JS 는 최고다 ! : )

🌿 GITHUB

profile
💻프론트엔드개발자

0개의 댓글

관련 채용 정보