
Today I Learn📖
- To do App 만들기 (강의)
To do App에서 사용되는 API를 통해 API 기초 사용법 확인하기 !
- todo 데이터 형태
⠀{ "_id": 할 일의 고유값. 숫자와 문자가 섞여있는 문자로 되어있음, "content": 할 일 text, "isCompleted": 할 일의 완료여부 }- 유저 목록 불러오기
=> API Url: https://todo-api.co.kr/users⠀fetch('https://todo-api.co.kr/users').then()...- 할 일 목록 불러오기 (
username에는 조회할 사람의 이름을 넣으면 됨)
=> API Url: https://todo-api.co.kr/:username⠀fetch('https://todo-api.co.kr/songhee').then()...- 할 일 추가하기
=> API Url: https://todo-api.co.kr/:username⠀/* * 할 일 추가하는 함수의 파라미터가 (url, options = {})임. * 이때 = {} 이건 따로 안 적으면 {} 을 기본값으로 갖겠다는 것 */ fetch('https://todo-api.co.kr/songhee', { method: 'POST', // POST 는 보내는 것 headers: { 'Content-Type': 'application/json' // 보내는 타입이 application/json라고 알리는 것, 보통 JSON 형태지만 다른 타입일 수도 있음(백엔드와 협의 후 결정하는 거니까..) }, body: JSON.stringify({ // 서버로 body에다가 JSON 타입으로 보내겠다는 것 content: '자바스크립트 공부하기' }) }).then(function(){ ... })- 할 일 삭제하기 (서버에서 불러온 개인의 각각 todo에는 고유의 id 존재,
todo_id에_id값 넣으면 됨)
=> API Url: https://todo-api.co.kr/:username/:todo_id⠀fetch('https://todo-api.co.kr/songhee/1a2s3d4f5g6', { method: 'DELETE' }).then(function(){ ... })- 할 일 완료 여부 토글 (
todo_id에 해당하는 todo의 완료 상태 토글)
=> API Url: https://todo-api.co.kr/:username/:todo_id/togglefetch('https://todo-api.co.kr/songhee/1a2s3d4f5g6/toggle', { method: 'PUT' }).then(function(){
내용이 렌더링 된 후, querySelectorAll("li"),forEach()로 모든 요소에 개별적으로 이벤트를 걸어도 됨
-> 이 방식은 렌더링 할 때마다 새로 이벤트를 걸기 때문에, 똑같은 이벤트가 id만 다르게 계속 걸리는 것, 만약 li가 동적으로 추가된 경우에는 id가 달라지지 않아 이벤트가 걸리지 않을 것
=> 대신 이벤트 버블링 이용하기
이벤트 델리게이션 (Event Delegation): 부모 요소에 하나의 이벤트만 걸고, 하위에서 생긴 이벤트들을 이벤트 버블링으로 감지해서 처리하는 것
-> 이벤트리스너로 컴포넌트 자체에 이벤트 걸기 (click, submit, ...)
-> 상위에 이벤트를 걸어뒀으니까, 하위에서 이벤트가 발생하면 시작한 곳부터 상위까지 계속 타고 올라가며 범인 찾음
-> 올라가다가 실제 이벤트를 발생시킨 곳을 발견하면 원하는 애가 맞는지 확인 후, 거기서 이벤트 작동
this.render = () => {
$todo.innerHTML = `
<ul>
${this.state.map(({ _id, content, isCompleted }) => `
<li data-id="${_id}" class="todo-item">
${isCompleted ? '<s>${content}</s>' : content} <button class="remove"> x </button>
</li>
`).join('')}
</ul>
`
}
$todo.addEventListener('click', (e) => {
const $li = e.target.closest('.todo-item') // closet을 통해 이벤트 발생한 곳에서 가장 가까운 class = todo-item 찾기
if ($li) { // 이벤트 발생한 곳 근처에 $li 있으면
const { id } = $li.dataset // 그 li에 있는 data-중 뒤가 id 인 것 가져오기
const { className } = e.target // 실제 이벤트를 발생시킨 곳(e.target)의 className 찾는 방법
if (className === 'remove') {
onRemove(id)
} else {
onToggle(id)
}
}
})
this.render ()
=> 리액트 등의 라이브러리는 내부 시스템으로 구현되어 있어서 이걸 직접 구현할 일이 없지만, 알고 있으면 좋은 개념 🥰
App.js에서 외부 컴포넌트를 import 해올 때
new 컴포넌트처럼 객체로만 생성하는 경우:
단발성으로, 생성과 동시에 동작하기 끝이기 때문에 값을 저장할 필요 없음
const 컴포넌트명 = new 컴포넌트처럼 변수로 생성하는 경우:
처음 렌더링된 후, 이 객체의 상태 등을 업데이트 하거나 메서드(이벤트)를 호출할 수 있기 때문
낙관적 업데이트
서버에 요청 보낸 게 100% 성공할 거라고 낙관적으로 생각하며, 서버에 요청하자마자 화면에도 요청한 값을 그려버리는 것
-> 서버에 요청하자마자 그 값으로 state를 업데이트 시키기
=> 서버에서 요청을 처리하는 게 오래걸려도, 사용자 입장에서는 바로 반영된 것 처럼 보이기 때문에 만족도 올라감
⠀
ex) 페이스북, ...
로컬 스토리지의 setItem(key, value), getItem(key, defaultValue), removeItem(key)를 사용해 Form의 input에서 입력 중인 입력값을 저장할 수 있음
-> 새로고침 해도 안 날아감
const $input = $form.querySelector('input')
$input.value = getItem(TODO_TEMP_SAVE_KEY, '')
$input.addEventListener('keyup', (e) => { // keyup으로 쓰면 키보드 눌렸다가 올라올 때마다 글자가 저장됨
setItem(TODO_TEMP_SAVE_KEY, e.target.value)
})
location.pathname: url의 도메인 뒤에 위치한 경로 반환, 쿼리 문자열이나 해시 제외
ex) https://example.com/products/item?id=123&category=books
⠀⠀⠀=> /products/item
location.search: url의 쿼리스트링 반환
-> 쿼리스트링은 ?으로 시작함, key=value 형태로 저장되어있음
ex) https://example.com/products/item?id=123&category=books
⠀⠀⠀=> ?id=123&category=books
/* 쿼리스트링은 ?name=songhee&position=front-end 형태니까
* &로 쪼갠 뒤, key=value의 조합을 object 형태로 만들고
* 그 형태 리턴하기
*/
// querystring.js
export const parse = (querystring) => {
querystring.split('&').reduce((acc, keyAndValue) => {
const [key, value] = keyAndValue.split('=')
if (key && value) acc[key] = value
return acc
}, {})
}
// App.js
import { parse } from "./querystring.js"
const { search } = location; // url에 특정 사용자를 나타내는 값이 있을 경우
if (search.length > 0) {
const { selectedUsername } = parse(search.substring(1))
if (selectedUsername) {
this.setState({
...this.state,
selectedUsername
})
await fetchTodos()
}
}
오늘은 여러 명이 사용하는 To do App 실습 강의였다.
실습 강의를 통해 컴포넌트 구조, api.js 세팅, storage.js 세팅 등을 복습할 수 있었다.
이벤트 델리게이션이라는 개념이 등장해서 찾아보다가 이벤트 버블링에 대해서도 공부했고, 낙관적 업데이트에 대해서도 알게되었다.
사용자 중심의 UI 구현에 대해 알아보고, 그걸 구현하는 과정까지 보면서 프론트엔드 개발자가 중요하게 생각해야하는 게 뭔지 고민해볼 수 있었다.
저번 시간에 배운 히스토리를 붙여서 url 바꾸는 것도 다시 복습돼서 좋았다.
그리고 로토 강사님 목소리 뒤로 깔리는 고냥이 소리.,, 대박 귀여워서 힐링됏다 !♥️