클론코딩해보기/TodoList

[Todo list] 06. 삭제, 정렬

js0616 2024. 8. 19. 23:40

삭제 기능

삭제 버튼 클릭시 해당 Item 이 삭제됨

-> this.state.items 의 해당 seq 가 제거

 

<App.js>  에서 deleteItem 함수 생성

  // 삭제하기
  deleteItem(contents) {
    // contents : Item.seq 를 받아온다.
    let seqArray = this.state.items.map(item => item.seq);
    let delIndex = seqArray.findIndex(item => item == contents);
    this.setState(this.state.items.splice(delIndex, 1));
  }

 

<Item.js> 까지 전달하고 '삭제' 버튼과 연결

    this.addEvent('click', '.deleteBtn', () => {
      deleteItem(item.seq);
    });

 

 


정렬 버튼 만들기

 

제목순/작성시간순...

오름 / 내림차순

 

// src/components/ItemSort.js
// 정렬 기능

import Component from '../core/Component.js';

export default class ItemSort extends Component {
  template() {
    return `
        <div>
          정렬:
            <select name='' class='sortType'>
                <option>제목</option>
                <option>시간</option>
            </select>
              <select name='' class='sortVal'>
                <option>오름차순 / 등록순</option>
                <option>내림차순 / 최신순</option>
            </select>
        </div>
        `;
  }

  setEvent() {}
}

 

this.state 에 정렬 방법에 관련된 state 생성

      sortVal: {
        type: 'title',
        way: 'asc',
      },

 

 

setSortType 함수에 들어오는 value 에 따라서

sortVal 의 type 이나 way 를 변경하여 setState 로 반영한다. 

  // 정렬
  setSortType(value) {
    let { type, way } = this.state.sortVal;

    if (['title', 'date'].includes(value)) {
      this.setState({ sortVal: { type: value, way: way } });
    } else {
      this.setState({ sortVal: { type: type, way: value } });
    }
  }

 

// src/components/ItemSort.js
// 정렬 기능

import Component from '../core/Component.js';

export default class ItemSort extends Component {
  template() {
    const { sortVal } = this.props;
    console.log('sortVal', sortVal);
    return `
        <div>
          정렬:
            <select name='' class='sortBtn'>
                <option value='title' ${sortVal.type == 'title' ? 'selected' : ''}>제목</option>
                <option value='date'  ${sortVal.type == 'date' ? 'selected' : ''}>시간</option>
            </select>
            <select class='sortBtn'>
                <option value='asc'  ${sortVal.way == 'asc' ? 'selected' : ''}>오름차순 / 등록순</option>
                <option value='desc' ${sortVal.way == 'desc' ? 'selected' : ''}>내림차순 / 최신순</option>
            </select>
        </div>
        `;
  }

  setEvent() {
    const { setSortType } = this.props;

    this.addEvent('change', '.sortBtn', e => {
      setSortType(e.target.value);
    });
  }
}

 


실제 정렬 동작

 

item의 순서를 바꾸게 되면 순서도 바뀌게 된다.

 

items: [
        {
          seq: 2,
          title: '그럼 혹시..',
          contents: '탕후루도 같이?',
          date: '2024.08.17. 02:45',
          workState: 'wait',
          write: false,
        },
        {
          seq: 1,
          title: '선배!!',
          contents: '마라탕 사주세요',
          date: '2024.08.17. 02:43',
          workState: 'wait',
          write: false,
        },
        {
          seq: 3,
          title: '웅나!',
          contents: '웅나나?',
          date: '2024.08.19. 20:00',
          workState: 'wait',
          write: false,
        },

 

 

this.state.items[{1} , {2} , {3} ,,, ]

this.state.items[{2} , {1} , {3} ,,, ] 와 과 같이 바뀌면

화면에 보여지는 내용도 바뀌어 원하는 결과를 노려볼 수 있다. 

-> 이는 배열 - 객체(key & value) 에 대해서 어떤 key 를 대상으로 value 를 오름/내림 정렬하여 list 에 저장 하는 문제 로 보인다. 

 

  // items 정렬
  setSort() {
    const { type, way } = this.state.sortVal;
    const items = [...this.state.items];
    let sorted_items = items.slice();
    // sorted_items.sort((item1, item2) => item1.seq - item2.seq); // 숫자
    sorted_items.sort((item1, item2) =>
      way == 'asc'
        ? item1[type].localeCompare(item2[type])
        : item2[type].localeCompare(item1[type]),
    );

    this.setState({ items: sorted_items });
  }

 

해당 함수 setSort() 를 적용할 곳은

1. 정렬 버튼을 조작

2. item 을 추가

3. item을 수정

 

수정

-> 시간에 대해서 초단위까지 필요함

->  currentTime 수정 및 표시는 분단위로 하기 위해서 slice 사용해서 second 는 제거

 

 

고민중..

setWorkCount 와 setSort 는 페이지 로딩시에 1번 동작해야 되는데 어떻게 해야될까.. useEffect 를 만들어야 될까.. 

 

<component.js> 를 수정하여 

loaded 함수 추가

constructor 에 맨 마지막에 this.loaded 로 추가하고 

 

App.js 에 최초 1회 실행할 함수를 집어넣었다. 

  loaded() {
    console.log(this, 'loaded');
    this.setWorkCount();
    this.setSort();
  }

 

기능은 원하는데로 잘 작동한다. 

 

전체 코드 확인

https://github.com/js0616/todoList

 


ps. 

 

console을 확인하면 App.js 렌더링 이후 각 item 들이 렌더링 되고 .. 그 이후에 loaded 가 실행되는데.. 

이후에 또 App 과 item 들이 2번더 렌더링 되는데... 

-> loaded 의 함수(setWorkCount , setSort ) 를 실행할때마다 다시 렌더링 되는듯 함.