[Day 36] Todo-List 실습 + 게시판 프로젝트

실습

Todo-List 실습

상태 변화와 화면 갱신의 방법

  1. 비관적(pessimistic) 업데이트
    • 사용자 입력 -> 수정 요청 -> (성공 시) 화면 갱신
    • 장점 : 개발자가 구현하기가 쉽다.
    • 단점 : 사용자가 이용할 때 불편하다.
  2. 낙관적(optimistic) 업데이트
    • 사용자 입력 -> 화면 갱신 -> 수정 요청
    • 단점
      • 수정 요청(통신)이 성공 했을 때와 실패 했을 때의 경우를 분리해서 생각해야 한다. (ex. 실패 시 화면 갱신 했던 것을 취소하고 원상복구 해줘야 한다.)
      • 개발자가 구현하기가 까다롭다.

로딩 인디케이터(Loading Indicator)

  • 비관적 업데이트를 할 경우 로딩 인디케이터를 통해 현재 동작 중이라는 것을 알려줘야 한다.

  • 비동기 함수 뒤에 로딩 인디케이터를 제거한다면 로딩 인디케이터가 먼저 사라지고 함수가 실행되는 것처럼 보인다.

    • 비동기 함수도 Promise를 반환하기 때문에, 비동기 함수를 실행했을 때 반환되는 Promise에는 비동기 함수 내부에서 반환한 값이 채워진다.

    • 이러한 성질을 이용해 비동기 함수 앞에 await 키워드를 넣어주면 비동기 함수가 모두 실행되고 난 다음에 로딩 인디케이터 제거 코드를 실행한다.

      // 폼에 할일 입력하고 전송 했을 때의 이벤트 리스너
      todoFormEl.addEventListener('submit', async e => {
        e.preventDefault()
        // Loading Indicator를 위한 loading class 추가
        document.body.classList.add('loading')
        const body = e.target.elements.body.value
        const res = await api.post('/todos', {
          body: body,
          complete: false
        })
        await drawTodoList()
        // 통신이 성공하고, 화면을 새로 그리고 나면 Loading Indicator를 제거해준다.
        document.body.classList.remove('loading')
      })
      

화면 갱신에 관한 생각들

  • 화면을 모두 다시 그리는 코드는 개발자에게는 좋지만, 기계에게는 나쁘다고 볼 수 있다.
  • 필요한 부분만 갱신하는 코드는 개발자에게는 매우 힘든일이지만, 기계에게는 좋다고 볼 수 있다.
  • 리액트는 개발자는 화면을 모두 다시 그리는 방식으로 코드를 작성하고, 기계는 필요한 부분만 갱신하는 방식으로 작동할 수 있도록 해주는 라이브러리다.

게시판 프로젝트

Parcel에서 환경변수 사용하기

  • .env 파일로부터 환경 변수를 로딩하기 위해 dotenv 라는 유틸리티를 활용한다.

json-server에 내장된 여러 기능

  • GitHub - json-server

  • Plural routes

    GET    /posts
    GET    /posts/1
    POST   /posts
    PUT    /posts/1
    PATCH  /posts/1
    DELETE /posts/1
    
  • Singular routes

    GET    /profile
    POST   /profile
    PUT    /profile
    PATCH  /profile
    
  • Filter

    • 식별자를 이용해 필요한 내용만 가져온다.
    GET /posts?title=json-server&author=typicode
    GET /posts?id=1&id=2
    GET /comments?author.name=typicode
    
  • Paginate

    • _page : 현재 페이지 번호
    • _limit : 한 페이지에 자료가 몇개 나올지
    GET /posts?_page=7
    GET /posts?_page=7&_limit=20
    
  • Sort

    • _sort : 뭘 기준으로 정렬할지
    • _order : asc / desc (오름차순 / 내림차순)
    GET /posts?_sort=views&_order=asc
    GET /posts/1/comments?_sort=votes&_order=asc
    // multiple fields
    GET /posts?_sort=user,views&_order=desc,asc
    
  • Slice

    GET /posts?_start=20&_end=30
    GET /posts/1/comments?_start=20&_end=30
    GET /posts/1/comments?_start=20&_limit=10
    
  • Operators

    • _gte (greater than or equal) : 크거나 같다.

    • _lte (less than or equal) : 작거나 같다.

      GET /posts?views_gte=10&views_lte=20
      
    • _ne (not equal) : ~가 아닌 것

      GET /posts?id_ne=1
      
    • like : ~가 포함된 것 (정규표현식 지원)

      GET /posts?title_like=server
      
  • Full-text Search

    • Add q (어느 속성에라도 포함되어 있다면 검색한다)

      GET /posts?q=internet
      
  • Relationships

    • _embed : to include children resource

      GET /posts?_embed=comments
      GET /posts/1?_embed=comments
      
    • _expand : to include parent resouce

      GET /comments?_expand=post
      GET /comments/1?_expand=post
      
    • 자료간의 관계설정

      GET  /posts/1/comments (댓글을 가져올 때)
      POST /posts/1/comments (댓글을 생성할 때)
      
    • 자식의 자식,부모 / 부모의 자식, 부모를 가져올 때

      • json server 자체에서는 요청 한번에 다 가져올 수는 없다.

      • 요청을 다시 한 번 보내야 한다.

      • URLSearchParams를 이용해야 한다.

        const params = new URLSearchParams()
        comments.forEach(c => {
          params.append('id', c.userId)
        })
              
        const {data: userList} = await api.get('/users', {
          params
        })
        
  • Database

    GET /db
    
  • Homepage

    GET /
    

URLSearchParams 사용하기

  • MDN - URLSearchParams

  • URLSearchParams : 여러개의 쿼리 스트링을 담을 수 있는 객체
  • 특징
    • 같은 이름의 쿼리 스트링을 여러번 쓸 수 있다!

댓글남기기