[React][Inflearn] 7. Hooks

sohwisu·2022년 9월 11일

[react][inflearn]

목록 보기
7/11

함수컴포넌트는 코드도 간결하고
생애주기에 맞춰서 특정코드가 실행되게 할 수 없었음
그래서 대신 사용되는게 훅!

훅 : 갈고리
원래 실행되는 코드에 갈고리처럼 같이 끼어들어 실행되게 하는 의미로 사용됨
<생애주기랑 느낌이 꽤 비슷하긴하다>

훅 앞에는 use를 붙여주어야 함!!
커스텀훅은 개발자 마음대로 이름을 지을 수 있으나
뒤에서 배울 훅의 규칙에 따라
use를 통해 해당 기능이 훅이라는 것을 명시해줘야함

대표적인 훅

useState
State를 사용하기 위한 Hook

예시 코드:

카운터라는 함수컴포넌트를 보여주는 코드인데.,,,
버튼 눌릴때마다 카운트 변수가 증가하는 방식임
문제는 재 렌더링이 안돼서 화면상에 표시가 안됨

그래서 useState를 통해서 재 렌더링이 될수있도록 해줘야함


해당과정은 Class컴포넌트에서 셋스테이트를 써서 컴포넌트를 업데이트하고
재렌더링하는 과정과 비슷하다고 보면된다.

Class 컴포넌트에서 setState는 하나를 사용해 모든 State값을 변경할 수 있었지만
해당경우에는 변수당 Set함수가 각각 존재한다. Count,SetCount..

useEffect

: side effect를 수행하기 위한 Hook

side effect : 부작용(사전) (부정적) 개발자가 의도치않은 코드요
근데 리액트에서 말하는 의미는 그냥 효과,,,영향,,,,사실상 effect
예를 들면 서버에서 데이터를 받아오거나 수동으로 DOM을 변경하는 것을 의미

이런 작업을 이펙트라고 부르는 이유는 이 작업이 다른컴포넌트에 영향을 미칠 수 있고
렌더링 중에는 작업이 완료될 수 없기 때문이다.,,
렌더링이 끝나고 진행되어야 하는 작업들임!

그래서 이러한 작업들이 side로 진행되게 한다는 의미에서 Side + effect의 의미로 받아들이면 됨

=> 리액트의 함수 컴포넌트에서 side effect를 실행 할 수 있게 해주는 Hook

의존성 배열의 내용 중 하나라도 변경되면 이펙트함수가 실행됨니다~
기본적으로 이펙트함수는 컴포넌트가 랜더링된 이후와 업데이트로 재 랜더링 된 이후에 실행됨니다
만약 이펙트함수가 마운트와 언마운트 시에 단 한번씩만 실행되게 하고자 한다면 의존성 배열에 빈 배열을 넣으면 됨
아래참고

이렇게 하면 해당 이펙트가 props나 state에 있는 어떤 값에도 의존하지 않음

의존성 배열을 생략하면 컴포넌트가 업데이트 될때마다 호출됨

useEffect(이펙트 함수); <= 이렇게 사용!

또한 Effect는 함수 컴포넌트 안에서 선언되기 때문에 해당 컴포넌트의
state와 props에 접근할 수도 있습니다

요약

useMemo()

: Memoized Value를 리턴하는 Hook

Memoization
: 최적화를 위해 사용하는 개념
-> 연산량이많이드는 함수의 호출결과를 저장해 두었다가 같은 값으로 함수를 호출하면 함수를 불러오는 것 대신에 이전에 저장해두었던 호출결과를 반환하는것

-> 호출시간 짧아진
-> 불필요한 중복연산x 컴퓨터의 자원을 적게씀
여기서 말하는 저장값이 Memoized Value이다.

의존성 배열 속의 변수가 변했을때만
새로 create함수를 호출하여 결과값을 반환하고, 변하지 않았을경우에는 기존에 불러두었던 값을 그대로 반환함
->컴포넌트가 다시 랜더링될때마다 연산량 높은 작업을 반복하는 것을 줄일 수 있음
->빠른 랜더링 속도

유즈메모훅을 사용할 때 기억해야할 점은

유즈메모가 전달되는 함수는 랜더링이 진행될때 실행됨
그렇기 때문에 일반적으로 랜더링 도중 진행되서는 안될 작업을 유즈메모에 넣으면 안댐

예를 들어서 useEffect훅에서 실행되어야할 sideEffect훅의 경우에
서버에서 데이터를 받아오거나 수동으로 DOM을 변경하는 작업을 하는데, 이는 랜더링 중에는 진행되면 안될 작업임 -> useMemo훅이 아닌 useEffect훅을 사용해야함

그런데 만약 useMemo훅에 의존성 배열을 넣지 않을 경우, 매 렌더링마다 함수가 실행됨
->쓰는 의미가 없음 어차피 연산 다하는데
의존성배열을 빈배열로 넣으면 컴포넌트 마운트시에만 호출이 됨.. 뭐 그렇게 써도 되긴하는데
근데 보통그렇게는 잘 안쓰고 변수를 넣어서 변수가 변화할때마다 호출되게 사용함

useCallback()

useMemo Hook과 유사하지만 값이 아닌 함수를 반환함
마찬가지로 의존성 변수와 함수를 파라미터로 받음

의존성 변수가 변화하게 되면 메모이지션된 함수를 반환함

컴포넌트 내 함수를 계속해서 재정의하는 것을 막는 역할을 함

불필요한 반복작업 방지

예를들어 아래코드를 보게되면

컴포넌트 내에서 정의한 함수를 자식함수에 props로 넘겨 사용하는 경우에,

부모컴포넌트 handleClick이 재 랜더링될 때 마다 자식컴포넌트 event도 재 랜더링됨

하지만 useCallback훅을 사용하면
특정변수의 값이 변한경우에만 함수를 <<재 정의>> 하게 되므로
자식컴포넌트도 불필요하게 재 랜더링이 일어나지않음

useRef()

Reference를 사용하기 위한 Hook

Reference : 특정 컴포넌트에 접근할 수 있는 객체
useRef hook은 이 객체를 반환함

Reference객체에는 current라는 속성이 있는데
이것은 현재 reference하고 있는 Element를 의미함


파라미터로 초깃값을 넣으면 해당 초깃값으로 초기화된 레퍼런스 객체를 반환합니다.
만약 초깃값이 null이라면 current의 값이 null인 레퍼런스 객체를 반환
이렇게 반환된 레퍼런스 객체는 컴포넌트의 라이프타임 전체에 걸쳐서 유지됨
즉, 컴포넌트가 마운트해제 될때까지는 유지가 된다는 소리
쉽게 말해 useRef Hook은 변경 가능한 커런트라는 속성을 가진 하나의 상자라고 생각하면 된다

잘 모르겟다 어렵네,,

직접 current속성이 포함된 객체를 만들어 쓰는것의 차이는
useRef hook은 매번 랜더링 될때 마다 같은 레퍼런스의 객체를 반환한다는 것임

useRef() Hook은 내부의 데이터가 변경되었을때 별도로 알리지 않음
-> current 속성이 변경된다고 해서 재 랜더링되거나,, 그러진 않음

따라서 ref에 DOM node가 연결되거나 분리 되었을때 어떤 코드를 사용하고 싶다면
Callback ref를 사용하십시오 휴-먼

Callback ref

DOM노드의 변화를 알기 원한다면,,,

React는 ref가 다른 node에 연결될때마다 Callback을 호출함니다
그게 필요할땐 useRef말구 Callback 쓰자,,,

Hook의 규칙

Hook은 단순한 Javascript 함수이지만, 지켜야할 규칙이 잇읍니다,,

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

여기서 최상위 레벨은 리액트 함수 컴포넌트의 최상위 레벨을 말하는것임
즉 반복문 조건문등의 함수 안에서 훅을 호출하면 안된다는거임

이 규칙에 따라

Hook은 컴포넌트가 렌더링 될 때마다 매번 같은 순서로 호출되어야 한다.
이렇게 해야 리액트가 다수의 useState hook과 useEffect hook의 호출에서
컴포넌트의 state를 올바르게 관리 할 수 있게됩니당

아래는 잘못된 Hook 사용법임

이코드는
if 조건문에 들어간 값이 참인 경우에만 useEffect훅을 호출할 수 있게 되어있다
이말인 즉슨 조건문의 결과에 따라 호출이 안될 수 있다는 것이기에 잘못된 사용임
꼭 최상위 단계에서만 호출하ㅏ세여어어어ㅓㅇ

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

일반적인 javascript함수에서는 부르지 말란 말입니다 홀홀
훅은 리액트 함수 컴포넌트에서 호출하던가 직접만든 커스텀 훅에서만 호출 할 수 있습니다.

eslnt-plugin-react-hooks

-개발에 도움되는 패키지
hook의 규칙을 따르도록 규제해줌
규칙을 따르는지도 분석 가능

Custom Hook 만드는 상황

custom Hook 추출

이름이 use부터 시작
내부에서 다른 hook 호출하는 Javascript 함수
파라미터, 리턴값을 개발자가 직접 설정할 수 있음
단순한 함수와도 같으나 use를 이용해서
단순한 함수가 아닌 커스텀 훅임을 인지시켜줌

해당 커스텀훅의 경우
useUserStatus
파라미터로 user id를 받아오는 커스텀 훅임

Custom Hook 사용하기

위 코드의 목표: User status와 user list item component의 중복된 로직을 제거하는 것
그리고 두개의 컴포넌트는 모두 사용자가 online상태인지 알기를 원했음
중복된 로직을 Useuserstatus로 추출했기때문에 이훅을 사용해 다음과 같이 코드를 변경가능

여러개의 컴포넌트에서 하나의 Custom Hook을 사용할 때
컴포넌트 내부에 있는 모든 state와 effects는 전부 분리되어 있다

그렇다면 Custom Hook은 어떻게 state를 분리하는가?
-> 각 Custom Hook 호출에 대해서 분리된 state를 얻게 됨

또한 하나의 컴포넌트에서 usestate등을 여러번 호출 할 수 있는 것 처럼
각 Custom Hook의 호출 또한 완전히 독립적이다.

그렇다면 이렇게 분리된 Hook들 사이에서
데이터를 공유하는 방법은 무엇인가>


Function에서
새로운 함수를 만들었는데,
보게되면 위의 useState에서 user ID를 만들고 그것이 바로 아랫줄에 파라미터로 적용됨
그래서 useUserStatus는 setuserid가 변경될때마다 기존의 아이디를 구독취소하고
새로운 아이디를 구독하게 됨

-실습
useCounter()
Custom Hook 만들기

profile
UDR Branding Manager

0개의 댓글