TIL 52 | React Hooks

dabin *.◟(ˊᗨˋ)◞.*·2021년 10월 24일
1

React

목록 보기
10/14
post-thumbnail

Hook이란?

Hook은 함수형 컴포넌트에서 React state와 라이프사이클을 연동(hook into)해주는 함수다. Hook은 class 안에서는 동작하지 않고, 함수형 컴포넌트에서 class 없이 Hook과 React를 사용할 수 있다.
참고링크

Hook 사용 규칙

  1. 최상위(at the top level)에서만 Hook을 호출해야 한다. 반복문, 조건문, 중첩된 함수 내에서 Hook을 실행하면 안된다.
  2. 함수 컴포넌트 내에서만 Hook을 호출해야 한다. 일반 JavaScript 함수에서는 Hook을 호출하면 안된다. (custom Hook 내에서는 일반 Javascript 함수여도 가능하다)

배열의 destructuring

class형 컴포넌트에서 지금까지 객체의 구조분해할당을 많이 사용했다.

const data = {id: 1, name: 'dabin'};
const { id, name } = data;

배열도 구조분해할당이 가능하다.

const [a, b, c, d] = [1, 4, 3, 2]
console.log(a, b, c, d)  // 1 4 3 2

state Hook도 배열의 구조분해할당이 적용된 것이다.

//useState는 아래 함수와 같은 모양이다.
function useState () {
  //code...
  return [state, setState]
}

//state Hook 컨벤션
const [state, setState] = useState(initialState);

//이후 return 내에서 state와 setState를 사용하면 된다

State Hook

const [state, setState] = useState(initialState);

// 안 좋은 예시
const [state, setState] = useState({
	color: "blue",
	name: "dabin".
})

//좋은 예시
const [color, setColor] = useState('red')
const [name, setName] = useState('dabin')

useState 하나에서 모든 값을 관리하기 보다는, 함께 변경되는 값끼리만 묶어 사용하기를 권장한다. 추가로, state에서 객체를 수정해야 할 때 아래와 같이 새로운 객체를 만들어서 그 객체에 변화를 주는 방식으로 코드가 작성되어야 한다는 점을 기억하자.

const [user, setUser] = useState({name: 'dabin', nickname: 'dabing'})

const onChange = e => {
  const { name, value } = e.target;
  setUser({
    ...user,
    [name]: value
  })
}

Effect Hook

useEffect(function);

useEffect는 함수 컴포넌트 내에서 side effects(컴포넌트 안에서 데이터를 가져오거나 구독하고 DOM을 직접 조작하는 작업 등)를 수행할 수 있게 해준다. 즉, class형 컴포넌트에서 사용하던 componentDidMount 나 componentDidUpdate, componentWillUnmount가 통합되었다고 생각하면 된다.

//update가 있을 때마다 실행
useEffect(() => {
	console.log("componentDidUpdate")
}) 

//[] 빈 배열을 두 번째 인자로 넣으면 최초 렌더링시 한 번만 실행
useEffect(() => {
	fetch();
}, [])

const fetch = async () => {
  const res = fetch('url');
  const data = await res.json();
  setData(data)
}

//state가 변화되었을 때만 실행
useEffect(() => {
   console.log("componentDidUpdate")
}, [state])

모든 useEffect()는 렌더링될 때 실행된다. 만약 렌더링이 될 때가 아닌, 그 이후 특정 시점에 useEffect()를 실행시키고 싶다면 아래와 같이 조건문을 사용해 코드를 짤 수 있다.

//flag가 true일 때만 로직 실행
useEffect(() => {
	if(!flag) return;
    //logins
}, [])

custom Hook

커스텀 훅을 통해 반복되는 로직을 쉽게 재사용할 수 있다.

fetch 함수가 많이 반복되니 hooks 폴더를 만들고, hook 코드들을 관리할 수 있도록 해보자.

import { useEffect, useState } from "react"

export const useFetch = ({ url, method = "GET" }) => {
  const [data, setData] = useState([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(false)
  
  useEffect(() => {
    fetch(url, { method })
      .then(res => res.json())
      .then(res => {
        setLoading(false)
        setData(res)
      })
      .catch(() => setError(true))
  }, [url])
  
  return { data, loading, error }
}

custom hooks를 적용해보자.

import { useFetch } from "../hooks";

const API = "http://localhost:8000/products";

function App() {
  const { data, loading, error } = useFetch({ url: API, method: "GET" })

  if (loading) return <div>Loading...</div>
  if (error) return <div>Error!</div>

  return <div>Component</div>
}
profile
모르는것투성이

0개의 댓글