관리 메뉴

흰둥씨의 개발장

[오늘의 React] Hooks 본문

[오늘의 공부]/React.js

[오늘의 React] Hooks

돈워리비해삐 2023. 3. 5. 00:54

v16.8에서 새롭게 등장한 개념

state와 생명주기 기능을 원하는 시점에 실행되도록 만든 함수

hook은 모두 'use' 로 시작

규칙

 

1. 무조건 최상위 레벨에서만 호출

반복문이나 조건문 또는 중첩 함수들 안에서 hook 호출 안됨

컴포넌트가 렌더링 될 때마다 매번 같은 순서로 호출되어야 함

 

2. 리액트 함수 컴포넌트에서만 hook 호출해야 함

리액트 함수 컴포넌트에서 호출하거나 커스텀 훅에서만 호출 할 수 있음

 

3. 커스텀 훅

use로 이름을 시작 -> 특정 함수 내부에서 훅을 호출하는지 알수 없기 때문에 규칙 위반 여부 자동 확인 x

내부에 다른 훅을 호출하는 단순한 자바스크립트 함수

파라미터로 무엇을 받을지, 어떤 것을 리턴해야 할지를 개발자가 정의

중복되는 로직을 커스텀 훅으로 추출하여 재사용성 높이기




· useState()​

state를 사용하기 위한 훅

변수 각각에 대한 set함수가 따로 존재

state 상태

리액트 컴포넌트 상태를 말하며 자바스크립트의 객체

리액트 컴포넌트의 변경 가능한 데이터

useState()

컴포넌트 안에 state를 생성하고 state값을 변경할 수 있는 함수로 생성하는 hook

// const [state이름, state변경함수] = useState(초기값)
const [state, setState] = useState();

특징

· 직접 변경 불가능

· 컴포넌트 안에서 state값이 변경되면 해당 컴포넌트는 재랜더링 됨

· state 값이 원시형(String, Number, Boolean)인 경우에는 해당 값을 바꾸면 바로 변경. 즉 재랜더링

· state 값이 참조형(Array, Object)인 경우 해당 값의 불변성을 유지하면서 변경해야 재랜더링 됨

· state에 담겨있는 기존 참조형 자료값을 바로 변경하는 것이 아닌 전개 연산자로 한 다음 변경해야 변경된 내용이 적용

· 렌더링이나 데이터 흐름에 사용되는 값만 state에 포함되어야 함

-> state가 변경될 경우 컴포넌트가 재렌더링 되기 때문에 데이터 흐름에 관련없는 값을 포함하면 성능 저하가 이루어질 수 있음

주의)

리액트에서는 state가 변경 되자마자 컴포넌트가 재호출되어 새로 만들어진 변수에 값이 저장되기 때문에 재할당 오류가 안생김.

const 상수 사용 가능

다만 ++, --같은 증감 연산자를 상태 내부에 사용하게 되면 컴포넌트가 재호출되기도 전에 내부적으로 값의 재할당이 발생하면서 const 지정시 오류 발생. let 변수 사용할 것

https://ko.reactjs.org/docs/hooks-state.html

 
 

· useRef()

 

DOM 요소에 직접 접근 가능

레퍼런스(특정 컴포넌트에 접근할 수 있는 객체)를 사용하기 위한 훅

렌더링될 때마다 같은 레퍼런스 객체 반환

 

useRef hook이 반환하는 ref 객체를 이용해서 자식 요소에 접근 가능

useRef에 의해 반환된 ref 객체는 변경되어도 컴포넌트가 재렌더링 되지 않음

 

.current 프로퍼티(속성)로 전달된 인자(initialValue)로 초기화 된 변경 가능한 ref 객체 반환

.current 프로퍼티에 변경 가능한 값을 담고 있는 “상자”와 같음

선언
const a = useRef(null)
const b = useRef()
const b = useRef(숫자) - 유지

DOM 연결
<태그 ref={xxx} />

xxx.current.yyy = ''
xxx.current.style.color = 'red'
xxx.current.style.fontSize = '20px'

주로 사용하는 곳 )

포커스, 텍스트 선택영역, 혹은 미디어의 재생을 관리할 때.

애니메이션을 직접적으로 실행시킬 때.

서드 파티 DOM 라이브러리를 React와 같이 사용할 때.

-> 주로 재랜더링을 피할 목적으로 사용

https://ko.reactjs.org/docs/refs-and-the-dom.html#gatsby-focus-wrapper

 

· useEffect()

사이드 이펙트(서버에서 데이터를 받아오거나 수동으로 DOM을 변경하는 등의 작업)를 수행하기 위한 훅

class 컴포넌트의
componentDidMount(),
componentDidUpdate(),
componentWillUnmount() 들의 기능을 하나로 통합해서 제공

 

즉, useEffect는

- 컴포넌트 생명주기마다 특정 기능을 실행 할 수 있게 해주는 hook
(함수형 컴포넌트의 sideEffect를 처리하기 위함)

- 컴포넌트 내부 html 렌더링 이후 실행됨
(비싼 연산을 수행해야 하는경우,
비싼 연산을 useEffect 안에 작성하면
html UI를 먼저 렌더링해주기 때문에
사용자가 화면로드를 오래 기다리지 않아도 됨)

선언된 컴포넌트의 props와 state에 접근 가능

useEffect()에서 리턴하는 함수는 clean-up함수로,
컴포넌트 Mount가 해제될 때 (=unmount될때)와 
의존성 배열의 값이 변경될 때 이전 이펙트를 정리하기 위해 호출됨

component의 생명주기 (lifecycle)

1) 컴포넌트생성 (mount),

2) 컴포넌트변경(state값 변경),

3) 컴포넌트소멸 (unmount)

 

useEffect(이펙트 함수, 의존성 배열)
useEffect( ()=> {}, []);

의존성 배열 안에 변수(state)를 넣으면 의존성 배열내 값이 하나라도 변경(update)되었을 때 이펙트 함수 실행
-> 의존성 배열 자리에 변수(state)가 있을때 return(()=>{})은 state변경시와 Unmount시 한번 실행됨

의존성 배열자리에 빈 배열을 넣으면 컴포넌트 Mount(이펙트함수)와 Unmount(clean-up함수있을때)시 단 한 번씩만 실행
-> 의존성배열 자리에 빈배열이 있을때 return(()=>{})은 Unmount시 한번 실행됨

 

useEffect가 하나의 매개변수 (콜백함수) 만 가지는 경우

useEffect(()=>{})


의존성 배열 생략시(=
매개변수로 콜백함수 하나만 가지는 경우)
컴포넌트가 업데이트, 재렌더링 될 때마다 실행
-> 의존성 배열 생략시에 return (()=>{})은 이펙트함수 실행전에 실행됨



 

 

 

 

컴포넌트 생성시 한번만 동작이 필요할 때

- 서버 데이터 비동기 통신시 처음 한 번만 호출하고자 할 때

useEffect( ()=> {
}, []); // [] 부분 비워 둠

 

 

컴포넌트가 변경될 때마다 실행

의존성배열에 특정값(state)을 등록하면 해당값이 변경될때마다 실행

- 이벤트가 발생할때마다 특정 정보값(state)이 변경되고 변경된 정보값이 화면에 갱신되서 출력되야 할 때

useEffect( () => {
  }, [state]); // state가 바뀔때마다 실행

 

 

컴포넌트 소멸시 (clean-up함수를 리턴시)

- window전역에 등록했던 이벤트를 다시 제거해야 될때

- 팝업이 사라지고나서 스크롤의 기능을 다시 활성화시켜야 될때

useEffect 안의 코드 실행 전에 항상 실행

렌더링 이전에 대한 정보들을 확인하고 싶다면 return을 사용

useEffect( ()=>{
  return ()=>{
   clean-up 함수 -> 언마운트될때 사용됨
  }
 } ,[state])

 

 

https://ko.reactjs.org/docs/hooks-effect.html

 


· useMemo()

Memorized value를 리턴하는 훅

연산량이 높은 작업이 매번 렌더링 될 때마다 반복되는 것을 피하기 위해 사용

렌더링이 일어나는 동안 실행되므로 렝더링이 일어나는 동안 실행되서는 안될 작업을 useMemo()에 놓으면 안 됨

의존성 배열에 들어있는 변수가 변했을 경우에만 새로 값 생성 함수 호출하여 결과값으로 반환

그렇지 않은 경우 기존 함수의 결과값 그대로 반환

의존성 배열을 넣지 않을 경우 렌더링이 일어날 때마다 매번 값 생성 함수가 실행되므로 의미 없음

const memorizeValue = useMemo(값 생성 함수, 의존성 배열);

 

 


· useCallback()

useMemo() 훅과 유사하나 값이 아닌 함수 반환

useCallback(콜백함수, 의존성배열)은 useMemo( ()=> 콜백함수, 의존성 배열)과 동일

컴포넌트 내 함수 정의시 렌더링 될 때마다 함수가 새로 정의되므로 useCallback() 훅을 사용하여 불필요한 함수 재정의 작업을 없애는 것

const memorizeCallbakc = useCallback(콜백함수, 의존성배열);

의존설 배열에 들어있는 변수가 변했을 경우에만 콜백 함수를 다시 정의해 리턴