Skip to content

Latest commit

 

History

History
117 lines (102 loc) · 5.06 KB

20210807.md

File metadata and controls

117 lines (102 loc) · 5.06 KB

React

인상 깊은 조언

  • TypeScript를 작은 프로젝트이든 큰 프로젝트이든 적용하는 것이 좋다. 운전을 한다면 집 앞 마트를 가든 강원도까지 가든 안전벨트를 매야 하는 것처럼 필수적인 것이다.
  • TypeScript는 업계 표준이다. 학습이 그렇게 어렵지 않으니 공부할 것.
  • 지식을 대하는 태도가 중요하다. 이미 난 이걸 마스터했다고 생각하는 순간 뇌는 더이상 학습하려고 하지 않는다. 뭐든지 아무리 쉬워보여도 더 배울수 있는 부분이 있는 담백한 마음가짐을 가져라.

배운 것들

useFetch 호출하는 상황 조건화하기

  • useFetch의 parameter를 shouldFetch라는 이름으로, 불리언 값을 반환하는 매개변수를 받아보자.
  • if (shouldFetch())로 조건문으로 fetchData()를 실행하는 부분을 감싼다.
  • shouldFetch 에 들어갈 함수를 만들어보자. 어떤 상황에서 true / false 를 반환해야 할까?
    • local storage에 storedPage가 currentPage를 포함하고 있다면 API 호출을 또 할 필요가 없다.
    • 그러므로 useFetch를 호출하면서 shouldFetch에 인자를 () => return storedPages.includes(currentPage)로 넣어준다.
// useFetch hook component

import { useState, useEffect } from 'react'
import { getQueryString } from '../utils/misc'

export default useFetch(apiUrl, params, headers, initialData, shouldFetch) {
  const [data, setData] = useState(initialData)
  const [isLoading, setIsLoading] = useState(false)
  const [error, setError] = useState(null)

  useEffect( () => {
    const fetchData = async () => {
      try {
        setIsLoading(true);
	const response = await fetch(`${apiUrl}${getQueryString(params)}`, {
	  method: 'GET',
	  mode: 'cors', 
	  cache: 'default',
	  headers,
	})
	const data = await response.json()
	setData((prevData => prevData.concat(data)))
	storeStorage(data)
      } catch (error) {
        console.error(error)
      } finally {
	setIsLoading(false)
      }
    }
    if (shouldFetch()){
      fetchData()
    }
  }, [apiUrl, params, headers])

  return  {
    data,
    isLoading, 
    hasError: error !== null,
    error,
  }
}

// useFetch utilizing component

const { 
  data: breeds, 
  isLoading, 
  hasError, 
  error 
} = useFetch(
  `${catApiUrl}/breeds`, 
  params, 
  catHeaders, 
  storedBreeds, 
  (newData) => {
    storeBreeds(storedBreeds.concat(newData))
  },
  () => {
    const hasFetched = storedPages.includes(currentPage)
    if (!hasFetched) {
      storePages(storedPages.concat(currentPage))
    }
    return !hasFetched
  }
)

Hooks의 도입 배경과 규칙

도입 배경

  • Hooks는 React version 16.8에서 추가됨
  • this 바인딩 리스크를 줄이기 위해
    • class component에서 setState로 상태 업데이트 할 때 this 바인딩이 중요하다(this.statethis로 접근하기 때문)
    • 이 this 바인딩을 잘못하면 이벤트핸들러에서 에러가 난다.
    • 이 문제를 arrow function을 사용함으로써 피햇지만, 그래도 이슈가 될 수 있다.
  • 로직을 추상화하여 재사용하기 위해
    • class component에서 API 호출하여 데이터 받아올 때, componentDidMount에서 API를 호출. 리렌더링하면 componentDidUpdate이 호출되면서 또 그 안에서 만약 props가 바뀐 바가 있다면 API 호출하는 코드가 있는데, 이는 두 개의 Life Cycle에 중복된 코드가 흩뿌려져 있는 셈이다.
    • Hook을 통해 우리가 로딩, 에러관리, 호출시점 판단 등을 useFetch에 다 몰아넣은 것처럼 한 번에 처리할 수 있다.
  • 위 두가지 이유로 hook이 등장햇다.

React Hook 규칙

  • 함수의 최상위에서만 호출 가능하다. hook과 hook 사이에 조건문이나 반복문 등이 끼어들 수 없으며, hook을 호출하는 것이 조건문이나 반복문 내부로 들어갈 수도 없다.
  • 함수 component 안에서, 또는 커스텀 hook 내부에서만 hook 호출이 가능하다. 일반적인 함수에서는 사용이 불가능하다.
window.addEventLister('mouseup', () => {
  useFetch(); // 불가능하다
};
  • 커스텀 훅 이름은 use로 시작해야 React가 커스텀 훅이라고 인식하기 용이하다.

Hooks 규칙이 있는 이유

  • React는 훅이 여러개 호출되더라도 처음에 전달받은 값이나 반환하는 값을 어딘가에 배열로 저장한다. 그래서 순서를 인식하고 보장한다.
  • component가 여러번 만들어져 여러번 사용되어도 React가 기억하는 순서를 통해 서로 다른 것임을 알 수 있다.
  • 훅의 호출순서가 매 렌더링마다 똑같이 유지되어야 일관성있게 렌더링, 기능들이 작동할 수 있다.
  • 조건문이나 반복문으로 호출이 바뀌면 안된다.

Sentry

느낀 점

  • 리액트 복습 및 숙제를 많이 못해서 내 자신에게도 마이너스겠지만 선생님한테 죄송
  • 온라인으로 하니까 더더욱 익명에 숨어 숙제를 안하는 것 같은데, 이번 주에는 좀 열심히 해야지