[React] Hooks (useState)

ryan·2020년 10월 8일
2

React

목록 보기
6/20
post-thumbnail

Hooks

함수 컴포넌트에서 React state의 생명주기 기능(Lifecycle features)을 연동(hook into) 할 수 있게 해주는 함수다. Hook은 class 안에서는 동작하지 않고, class 없이 React를 사용할 수 있게 해준다.

Hooks를 사용하는 이유

  • 컴포넌트 사이에서 상태와 관련된 로직을 재사용하기 어렵다.
  • 복잡한 컴포넌트들을 이해하기 어렵다.
  • Class는 복잡해서 사람과 기계를 혼동시킨다. (상속을 받을 경우 State, Action을 분리하여 생각할 수 없다.)

Hooks 사용 규칙

1. 최상위에서만 Hook을 호출해야 한다.

반복문, 조건문, 중첩된 함수 내에서 Hook을 실행하면 안된다.

import React, { useState } from "react"

function Hooks(props) {
  if(!props.isExist) return;
  const [state, setState] = useState(); // 에러 발생!
}

// react가 여러 hooks를 구분 할 수 있는 유일한 정보는
// Hooks가 사용된 순서 밖에 없기때문이다.

2. React 함수 컴포넌트 내에서만 Hook을 호출해야 한다.

일반 JS 함수에서는 Hook을 호출해서는 안된다. 단, 직접 작성한 custom Hook에서는 Hook을 호출할 수 있다.

State Hook (useState)

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

상태 유지 값과 그 값을 갱신하는 함수를 반환한다. 최초로 렌더링을 하는 동안, 반환된 state(state)는 첫 번째 전달된 인자(initialState)의 값과 같다.

setState 함수는 state를 갱신할 때 사용한다. 새 state 값을 받아서 컴포넌트 리렌더링을 큐(queue)에 등록한다.

setState(newState + 1); // setState와 동일하게 비동기 업데이트
setState(prev => prev + 1);
this.setState(prev =>)

다음 리렌더링 시에 useState를 통해 반환 받은 첫 번째 값은 항상 갱신된 최신 state가 된다.

상태 값을 관리할 때는 함께 변화하는 값들끼리 나누어서 여러 state 변수로 나누는 것을 추천한다.

function Box() {
  const [state, setState] = useState({left: 0, top: 0, width: 100, height: 100 })
// 이렇게 보다는 아래와 같이 나누자
  }
function Box() {
  const [position, setPosition] = useState({ left: 0, top: 0 });
  const [size, setSize] = useState({ width: 100, height: 100 });
  
  useEffect(() => {
    function handleWindowMouseMove(e) {
      setPosition({ left: e.pageX, top: e.pageY });
    }
    // ...

함수는 상태를 저장하지 않는다고 했었지않았나?

함수는 실행이 완료되면 함수 내에서 사용했던 모든 메모리들을 정리(Garbage collection)하는데 실행이 끝나고도 메모리에 스스로를 남겨둘 수 있는 방법(클로저)이 있다.

함수형 컴포넌트는 Hooks를 사용하면서 상태 관리가 가능해졌다. Hooks에서 state를 저장하려면 useState()를 사용한다. useState 역시 함수이고, 클로저를 이용해서 변수를 저장한다.

cont useState = (init = undefined) => {
  lef value = init
  const getter = () => value
  const setter = next => (value = next)
  
  return [getter, setter]
}

const [state, setState] = useState("클로저")

초기값을 받아 내부의 지역변수 value에 할당한다. 내부 함수 getter()는 지역변수 init을 바라보고 있다. 또 다른 내부 함수 setter()은 next라는 인자를 받아서 value의 값을 수정한다. 이후 다시 getter()을 호출하게 되면 변경된 value의 값을 호출하게 된다.

두 함수는 배열 형태로 리턴되고 useState를 사용할 때는 배열 구조분해 할당 형태로 많이 사용하게 된다. 위의 경우 내부 함수가 지역 변수를 참조하고 있으므로 사라지지 않는다. 또한 외부로 노출된 getter, setter 함수를 통해 내부 변수에 지속적으로 접근하고, 호출/재할당을 할 수 있다. 이는 클래스형 컴포넌트에서 state가 해온 역할과 동일하다.

profile
👨🏻‍💻☕️ 🎹🎵 🐰🎶 🛫📷

3개의 댓글

comment-user-thumbnail
2020년 10월 9일

👏🏻👏🏻👏🏻 어제보다 오늘 더 나은 라연킴 응원합니다 🤗 👏🏻👏🏻👏🏻

1개의 답글
comment-user-thumbnail
2021년 1월 18일

감사합니다 이해가 잘되네요

답글 달기