TIL React Hook 공식문서 파헤치기

flobeeee·2021년 2월 18일
0

Today I Learned

목록 보기
7/35
post-thumbnail

리액트에 대한 전반적인 이해가 끝나자마자 훅을 배우게 되었다.
React Hook 은 클래스 컴포넌트를 사용하지 않고, 함수 컴포넌트 내에서 상태를 쓸 수 있는 새로운 기능이다. (나온지 1년도 안돼서 아직 다들 배우는 입장이라고 한다.)

현재 리액트 공식문서는 class 컴포넌트를 메인으로 소개하는데,
조만간 함수 컴포넌트를 메인으로 소개한다는 소식을 들었다.

그래서 이 친구도 파헤칠 필요가 있다. 떠오르는 별이니까..🌟

🌟 Class 컴포넌트의 문제점

과제를 진행하면서, 의문이 들었던 부분이었다.

  1. this의 사용법을 알아야만 쓸 수 있다. 특히 handler를 this로 bind 해주는 부분은, 이해하려고 하지도 않았고 솔직히 그냥 틀이라고 생각했다. (= 외웠다.)

  2. 복잡한 lifeCycle. 코드를 실행하는 순서를 제어할 수 있다고 하지만, 실제로 과제를 구현할 때, componentDidMount(), componentWillUnmount()등을 사용하지 않고 구현했다. 굳이 필요성을 못느꼈다.

  3. 여러개의 컴포넌트 참조. props 내려꽂기나 state 끌어올리기를 할 때, 디버깅이 어려웠다. 디버깅을 할 때, 거꾸로 올라가야하는 데 부모 컴포넌트를 직관적으로 확인할 수 없어서 힘들었다. 이게 컴포넌트 깊이가 몇개 없어서 그렇지, 큰 프로젝트로 진행한다면 골치아플 것이라는 생각을 했다.

Hook의 탄생도 이런 문제점때문이라고 한다. 반겨주자.
공식문서 Hook의 소개에서 더 자세한 이유를 알 수 있다.

🌟 Hook 개요

  • 버튼을 클릭하면 값이 증가하는 간단한 카운터 예시
import ReactDOM from "react-dom";
import React, { useState } from 'react'; // useState가 바로 Hook 입니다

function Example() {
  // "count"라는 새 상태 변수를 선언합니다
  const [count, setCount] = useState(0); // state, 0 으로 초기값 넣어줌

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
    <Example />,
  rootElement
);

Hook을 호출해 함수 컴포넌트(function component) 안에 state를 추가했습니다. useState는 현재의 state 값과 이 값을 업데이트하는 함수를 쌍으로 제공합니다. 우리는 이 함수를 이벤트 핸들러나 다른 곳에서 호출할 수 있습니다. 이것은 class의 this.setState와 거의 유사하지만, 이전 state와 새로운 state를 합치지 않는다는 차이점이 있습니다.

useState는 인자로 초기 state 값을 하나 받습니다. 카운터는 0부터 시작하기 때문에 위 예시에서는 초기값으로 0을 넣어준 것입니다. this.state와는 달리 setState Hook의 state는 객체일 필요가 없습니다. 물론 원한다면 그렇게도 가능하지만요. 이 초기값은 첫 번째 렌더링에만 딱 한번 사용됩니다.


  • 여러 state 변수 선언하기

하나의 컴포넌트 내에서 State Hook을 여러 개 사용할 수도 있습니다.

function ExampleWithManyStates() {
  // 상태 변수를 여러 개 선언했습니다!
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
  // ...
}

배열 구조 분해(destructuring) 문법은 useState로 호출된 state 변수들을 다른 변수명으로 할당할 수 있게 해줍니다. 이 변수명은 useState API와 관련이 없습니다. 대신에 React는 매번 렌더링할 때 useState가 사용된 순서대로 실행할 것입니다. 왜 이렇게 동작하는지는 나중에 살펴보겠습니다.

(리액트를 활용하면서 구조분해문법을 왜 열심히 공부하라고 했었는지 깨달았다)

🌟 Hook 사용규칙

Hook은 그냥 JavaScript 함수이지만, 두 가지 규칙을 준수해야 합니다.

  • 최상위(at the top level)에서만 Hook을 호출해야 합니다. 반복문, 조건문, 중첩된 함수 내에서 Hook을 실행하지 마세요.

  • React 함수 컴포넌트 내에서만 Hook을 호출해야 합니다. 일반 JavaScript 함수에서는 Hook을 호출해서는 안 됩니다.

🌟 State Hook 사용하기

  • Hook과 함수 컴포넌트
const Example = (props) => {
  // 여기서 Hook을 사용할 수 있습니다!
  return <div />;
}

// or

function Example(props) {
  // 여기서 Hook을 사용할 수 있습니다!
  return <div />;
}

함수 컴포넌트를 “state가 없는 컴포넌트”로 알고 있었을 겁니다. 하지만 Hook은 React state를 함수 안에서 사용할 수 있게 해줍니다.

Hook은 클래스 안에서 동작하지 않습니다. 하지만 클래스를 작성하지 않고 사용할 수 있습니다.

  • Hook 이란 ?

Hook은 특별한 함수입니다. 예를 들어 useState는 state를 함수 컴포넌트 안에서 사용할 수 있게 해줍니다. 다른 Hook들은 나중에 살펴봅시다!

언제 Hook을 사용할까? 함수 컴포넌트를 사용하던 중 state를 추가하고 싶을 때 클래스 컴포넌트로 바꾸곤 했을 겁니다. 하지만 이제 함수 컴포넌트 안에서 Hook을 이용하여 state를 사용할 수 있습니다.

  • state 가져오기

클래스 컴포넌트는 count를 보여주기 위해 this.state.count를 사용합니다.
<p>You clicked {this.state.count} times</p>

반면 함수 컴포넌트는 count를 직접 사용할 수 있습니다.
<p>You clicked {count} times</p>

  • state 갱신하기

클래스 컴포넌트는 count를 갱신하기 위해 this.setState()를 호출합니다.

<button onClick={() => this.setState({ count: this.state.count + 1 })}>
    Click me
  </button>

반면 함수 컴포넌트는 setCount와 count 변수를 가지고 있으므로 this를 호출하지 않아도 됩니다.

  <button onClick={() => setCount(count + 1)}>
    Click me
  </button>

🌟 Effect Hook 사용하기

import ReactDOM from "react-dom";
import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
    <Example />,
  rootElement
);

🌟 Hook API

  • 기본 Hook
    • useState
    • useEffect
    • useContext
  • 추가 Hooks
    • useReducer
    • useCallback
    • useMemo
    • useRef
    • useImperativeHandle
    • useLayoutEffect
    • useDebugValue

배워야할 훅이 많다. 차근차근 익혀보도록 하자.

profile
기록하는 백엔드 개발자

0개의 댓글