React Hook

이정인·2021년 9월 27일
0

TIL

목록 보기
2/7

공식 문서를 읽고 정리한 내용

Hook을 사용하는 이유

  1. 컴포넌트 사이에서 상태 로직을 재사용하기 어렵다.

    Hook을 사용하면 컴포넌트로부터 상태 관련 로직을 추상화 할 수 있음. 즉 여러 컴포넌트들에서 반복되는 로직을 훅으로 만든 다음 import 해서 사용할 수 있고 이를 이용해서 독립적인 테스트와 재사용이 가능해진다.

    Hook은 계층의 변화 없이 상태 관련 로직을 재사용할 수 있도록 도와준다.

  2. 복잡한 컴포넌트들은 이해하기 어렵다.

    생명주기 메서드를 기반으로 로직을 나눌 경우 서로 연관 없는 로직들이 포함되어 버그가 쉽게 발생하고 무결성을 헤친다. Hook을 통해 서로 비슷한 것을 하는 작은 함수의 묶음으로 컴포넌트를 나누는 방법을 사용할 수 있다. (데이터 불러오기, 구독 설정) 또 이러한 로직의 추적을 쉽게 할 수 있도록 reducer 를 활용해 컴포넌트의 지역 상태 값을 관리하도록 할 수 있음.

  3. Class 없이 react 기능을 사용하기 위해서

State Hook

하나의 컴포넌트 내에서 State Hook을 여러개 선언 가능하고 각각의 setter와 같이 선언된다. useSate을 이용해 초기값을 지정하면 첫 번째 렌더링에만 딱 한 번 사용된다.

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

Effect Hook

React 컴포넌트 안에서 데이터를 가져오거나 구독하고 DOM을 직접 조작하는 작업을 side effects 또는 effects라고 한다. 다른 컴포넌트에 영향을 줄 수도 있고, 렌더링 과정에서는 구현할 수 없는 작업이기 때문이다. useEffect는 이러한 수행을 위한 것으로 class에서 생명주기가 하나로 통합된 것으로 보면 된다. 매 렌더링 이후에 effects를 실행함

Hook 사용 규칙

  • 최상위에서만 Hook을 호출해야함
  • React 함수 컴포넌트 내에서만 Hook을 호출해야함

Custom Hook

use 로 시작하고 안에서 다른 Hook을 호출한다면 custom hook.

Reducer Hook

state들이 서로 연관 있을때

const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

dispatch를 통해 type, payload 를 받아서 reducer 를 실행할 수 있다.

만약 Reducer에서 현재 state와 같은 값을 반환하는 경우 React는 자식을 리렌더링하거나 effect를 발생하지 않는다.

useCallback

메모이제이션된 콜백을 반환한다. 콜백의 의존성이 변경되었을때만 버전이 업데이트 되므로 불필요한 렌더링을 줄일 수 있다.

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

useMemo

생성 함수와 의존 배열을 전달하면 메모이제이션된 값을 반환함. 의존성이 변경되었을 때에만 메모이제이션된 값만 다시 계산하므로 렌더링 시의 고비용 계산을 방지해 최적화할 수 있다.

useMemo로 전달된 함수는 렌더링 중에 실행되므로 렌더링 중에는 하지 않는 것을 이 함수내에서 하면 안됨. (ex. 사이드 이펙트)

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

useRef

어떤 가변 값을 유지하는데에 편리함

const hideBy = useRef<HideBy | null>(null);

0개의 댓글