본문 바로가기
React Native

0015. Front-end 공부하기6 - Hooks (Feat. 처음 만난 리액트)

by 보초코더^_^;; 2023. 12. 22.
반응형

섹션 7. Hooks

1강. Hooks의 개념과 useState, useEffect

Hooks

리액트 컴포넌트 : Function Component, Class Component

Function Component Class Component
- state 사용 불가
- Lifecycle에 따른 기능 구현 불가
- Hooks
- 생성자에서 state를 정의
- setState() 함수를 통해 state 업데이트
- Lifecycle methods 제공

※ state를 이용해서 렌더링에 필요한 데이터를 관리함

  • 클래스 컴포넌트에서는 생성자, 컨스트럭터에서 state를 정의하고 setState 함수를 통해 state를 업데이트
  • class 컴포넌트는 state와 관련된 기능뿐만 아니라 컴포넌트의 생명 주기 함수들까지 모두 명확하게 정의되어 있기 때문에 잘 가져다 쓰기만 하면 됨
  • 함수 컴포넌트는 클래스 컴포넌트와 다르게 코드도 간결하고 별도로 state를 정의해서 사용하거나 컴포넌트의 생명 주기에 맞춰 어떤 코드가 실행되도록 할 수 없다. 따라서, 함수 컴포넌트에 이런 기능을 지원하기 위해 나온 것이 바로 Hook이다.
  • Hook을 사용하면 함수 컴포넌트도 클래스 컴포넌트의 기능을 모두 동일하게 구현할 수 있게 되는 것.

 

Hook : 갈고리

  • 프로그래밍에서는 원래 존재하는 어떤 기능에 갈고리를 거는 것처럼 끼어 들어가 같이 수행되는 것을 의미
  • 비슷하게 자주 사용 : webhook
  • 리액트의 hook도 마찬가지로 리액트의 state와 생명주기 기능의 갈고리를 걸어 원하는 시점에 정해진 함수 실행
    -> 이 때, 실행되는 함수를 hook이라고 부름
  • 앞에 use를 붙임(각 기능을 사용하겠다는 뜻)

 

1) useState()

  • 가장 대표적이고 많이 사용되는 훅
  • state를 사용하기 위한 hook
  • 함수 컴포넌트에서는 기본적으로 state를 제공하지 않기 때문에 class 컴포넌트처럼 state를 사용하고 싶으면 useState hook을 사용해야 한다.

useState() 사용법

  • 파라미터로 선언할 state의 초기값이 들어감
  • 초기값을 넣어 useState를 노출하면 return 값으로 배열([ ])이 나옴
  • 클래스 컴포넌트에서는 setState 함수 하나를 사용해서 모든 state 값을 업데이트할 수 있었지만, useState는 변수 각각에 대해 set 함수가 따로 존재

 

2) useEffect()

  • 대표적이고 많이 사용되는 훅
  • Side effect를 수행하기 위한 Hook 
  • 사이드 이펙트 : 효과, 영향
  • 예 : 서버에서 데이터를 받아오거나, 수동으로 DOM을 변경하는 등의 작업 의미
  • 이펙트라고 부르는 이유 : 
    - 다른 컴포넌트에 영향을 미칠 수 있으며, 렌더링 중에는 작업 완료 불가능
    - 렌더링이 끝나야 작업이 진행됨
  • 리액트의 함수 컴포넌트에서 Side effect를 실행할 수 있게 해주는 Hook
  • componentDidMount, componentDidUpdate, componentWillunmount -> 하나로 통합해서 제공, useEffect Hook만으로 생명 주기 함수와 동일한 기능 수행 가능
  • <요약>
    컴포넌트가 마운트 된 이후,
    의존성 배열에 있는 변수들 중 하나라도 값이 변경되었을 때 실행됨
    의존성 배열에 빈 배열([ ])을 넣으면 마운트와 언마운트시에 단 한 번씩만 실행됨
    의존성 배열 생략 시 컴포넌트 업데이트 시마다 실행됨.
    return : 컴포넌트가 마운트 해제되기 전에 실행됨

useEffect 사용법

  • 첫번째 파라미터 : 이펙트 함수
    두 번째 파라미터 : 의존성 배열(이펙트가 의존하고 있는 배열, 배열 안에 있는 변수 중에 하나라도 변경되었을 때 이펙트 함수 실행)
  • 이펙트 함수 : 처음 컴포넌트가 렌더링 된 이후와 업데이트로 인한 재렌더링 이후에 실행

 

  • Effect function이 mount, unmount시에 단 한 번만 실행되도록 하는 방법
    - 의존성 배열에 빈 배열을 넣는다.

의존성 배열에 빈 배열

 

  • 컴포넌트가 업데이트 될 때마다 호출되도록 하는 방법
    - 의존성 배열을 생략한다.
    - 의존성 배열 없이 useEffect를 사용하면 리액트는 DOM이 변경된 이후에 해당 이펙트 함수를 실행하라는 의미로 받아들임
    - 매번 렌더링 될 때마다 이펙트가 실행됨

의존성 배열 생략

 

  • 이펙트는 함수 컴포넌트 안에서 선언되기 때문에 해당 컴포넌트의 props와 state에 접근 가능

 

예제1 : useEffect Hook을 사용하는 경우, 생명주기 함수의 기능과 동일하게 만듦

 

  • 의존성 배열 없이 useEffect를 사용했기 때문에 React는 DOM이 변경된 이후에 이펙트 함수를 실행하라는 의미로 받아들임
    - 매번 렌더링 될때마다 렌더링
    - 결국, componentDidMount, componentDidUpdate와 비슷한 기능을 하는 것
  • 이펙트는 함수 컴포넌트 안에서 선언되기 때문에 해당 컴포넌트의 props와 state에 접근할 수 있음
    - 위에서는 count라는 state에 접근하여 해당 값이 포함된 문자열을 생성하여 사용하는 것을 볼 수 있음

 

예제2 : componentWillMount와 동일한 기능

 

  • useEffect에서 서버API를 사용하여 사용자의 상태를 구독하고 있음
  • useEffect에서 리턴하는 함수는 컴포넌트가 mount 해제, 즉 unmount 될 때 호출됨
    - useEffect의 리턴 함수는 unmount 함수가 하는 역할과 동일함

예제3 : 두 개의 useEffect hook을 사용

 

  • useState Hook과 useEffect Hook을 각각 두개씩 사용

요약

 

 

2강. useMemo, useCallback, useRef

memo hook : useMemo 혹은 memorized value를 리턴하는 훅

momoized value : memoization의 결괏값

 

Memoization

  • 최적화를 위해 사용하는 개념
  • 메모를 했다가 다시 사용하는 것처럼 연산량이 많이 드는 함수의 호출 결과를 저장해 두었다가 같은 입력 값으로 함수를 호출하면, 새로 함수를 호출하지 않고 이전에 저장해 놨던 호출 결과를 바로 반환하는 방법
    함수 호출 결과를 받기까지 걸리는 시간 단축, 불필요한 중복 연산 X

 

 

1) useMemo()

  • 컴포넌트가 다시 렌더링 될 때마다 연산량이 높은 작업을 반복하는 것을 피할 수 있다. (빠른 렌더링 속도)
  • 렌더링이 일어나는 도중에 실행됨 -> 렌더링이 일어나는 동안 실행되어서는 안 될 작업을 useMemo의 함수에 넣으면 안 됨
    -> useEffect hook을 사용해야 함

의존성 배열을 넣지 않은 경우

  • 의존성 배열을 넣지 않을 경우, 렌더링이 일어날 때마다 매번 creat 함수가 실행됨
  • 즉, useMemo 훅에 의존성 배열을 넣지 않고 사용하는 것은 아무런 의미가 없음

 

의존성 배열을 빈 배열로 넣은 경우

  • 의존성 배열에 빈 배열을 넣게 되면, 컴포넌트가 마운트 될 때만 creat 함수가 호출됨
  • 즉, mount 이후에는 값이 변경되지 않는 것
  • 마운트 시점에만 한번 값을 계산할 필요가 있을 경우에는 이렇게 사용
  • 대부분은 useMemo 훅에 의존성 배열의 변수들을 넣고, 해당 변수들의 값이 바뀜에 따라 값을 계산할 경우에 사용함

 

2) useCallback()

  • useMemo() Hook과 유사하지만, 값이 아닌 함수를 반환함
  • 컴포넌트가 렌더링 될 때마다 매번 함수를 새로 정의하는 것이 아니라, 의존성 배열의 값이 바뀐 경우에만 함수를 새로 정의해서 리턴해 줌

 

useCallback 사용법

 

  • useCallback 훅은 useMemo 훅과 마찬가지로 함수와 의존성 배열을 파라미터로 받음
  • useCallback 훅에서는 파라미터로 받는 이 함수는 'callback'이라고 부름
  • 의존성 변수가 하나라도 변경되면 메모이제이션된 함수를 반환함

두 줄의 코드는 동일한 역할을 한다.

 

3) useRef()

  • Reference를 사용하기 위한 Hook, 레퍼런스 객체를 반환함
  • Reference : 특정 컴포넌트에 접근할 수 있는 객체
  • currnet 속성 : 현재 레퍼런스 하고 있는 엘리먼트를 의미
    refObject.current

useRef 훅 사용법

  • 파라미터로 초깃값을 넣으면 해당 초깃값으로 초기화된 레퍼런스 객체를 반환한다.
  • 초깃값이 null이라면 current의 값이 null인 레퍼런스 객체가 반환됨
  • 반환된 레퍼런스 객체는 컴포넌트의 라이프타임 전체에 걸쳐서 유지됨
    - 컴포넌트 마운트 해제 전까지 계속 유지
  • useRef : 변경 가능한 current라는 속성을 가진 하나의 상자라고 생각하면 됨
  • useRef 훅은 매번 렌더링 될 때마다 항상 같은 레퍼런스 객체를 반환함
  • useRef 훅은 내부의 데이터가 변경되었을 때, 별도로 알리지 않는다.
    - 커런트 속성을 변경한다고 해서 재렌더링이 일어나지는 않는다.

 

4) Callback ref

  • ref에 돔노드가 연결되거나 분리되었을 경우에 어떤 코드를 실행하고 싶다면 Callback ref를 사용
    - 돔노드의 변화를 알기 위한 가장 기초적인 방법
  • 자식 컴포넌트가 변경되었을 때 알림을 받을 수 있고, 이를 통해 다른 정보들을 업데이트할 수 있다.

 

3강. Hook의 규칙

1. Hook은 무조건 최상위 레벨에서만 호출해야 한다.

  • 최상위 레벨 : React 함수 컴포넌트의 최상위 레벨
    - 즉, 반복문, 조건문, 중첩 함수 안에서 Hook을 호출하면 안 된다는 것.
  • Hook은 컴포넌트가 렌더링 될 때마다 매번 같은 순서로 호출되어야 한다.

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

  • 일반적인 JavaScript 함수에서 호출하면 안 됨
  • 리액트 함수 컴포넌트에서 호출하거나, 직접 만든 커스컴 훅에서만 호출할 수 있음

eslint-plugin-react-hooks

- Hook의 규칙을 따르도록 강제해 주는 플러그인

- eslint : JavsScript 코드에서 발견되는 문제 패턴을 식별하기 위한 정적코드분석도구

https://www.npmjs.com/package/eslint-plugin-react-hooks 

 

eslint-plugin-react-hooks

ESLint rules for React Hooks. Latest version: 4.6.0, last published: 2 years ago. Start using eslint-plugin-react-hooks in your project by running `npm i eslint-plugin-react-hooks`. There are 8558 other projects in the npm registry using eslint-plugin-reac

www.npmjs.com

 

 

Custom Hook 만들기

  • 여러 컴포넌트에서 반복적으로 사용되는 로직을 Hook으로 만들어 재사용하기 위함
  • 이름이 use로 시작하고 내부에서 다른 Hook을 호출하는 하나의 자바스크립트 함수

 

Custom Hook 사용하기

  • Custom Hook의 이름은 꼭 use로 시작해야 한다!
    - Hook인지 모른다면 Hook의 규칙 위반 여부를 자동으로 확인할 수 없다.
  • 여러 개의 컴포넌트에서 하나의 Custom Hook을 사용할 때, 컴포넌트 내부에 있는 모든 state와 effect는 전부 분리되어 있다.
  • 각 Custom Hook 호출에 대해서 분리된 state를 얻기 때문에 완전 독립적

 

Hook들 사이에서 데이터를 공유하는 방법

useState(1) -> userID 반환

userID 변경 -> useUserStatus(userID) 변경 (다른 데이터 반환)

 

 

4강. (실습) Hooks 사용해 보기

1) useCounter() Custom Hook 만들기

 

 

2) Accomodate 컴포넌트 만들기

 

 

3) index.js 수정하기

 

 

그 뒤에 npm start를 하면

짜잔!

 

그런데 이쯤 와서 보니까 점점 개념이 어려워지는 것 같다.

코딩을 한다고는 하는데 화면에 있는 코드 그대로 따라서 쓰는 거라 스스로 한다고 했을 때 할 수 있을지는 너무나도 큰 의문이다. 그래도 일단 한 발씩 떼는 중이다.

어떻게든 되겠지

 

isFull이 True가 되면 정원이 가득찼다는 메시지가 나온다.

 

 

반응형