기은P
시간이 멈추는 장소
기은P
  • Programming (272)
    • 개발노트 (1)
    • FrontEnd (56)
      • ES&JS 문법 (14)
      • HTML&CSS (4)
      • React 기본 (18)
      • React 심화 (12)
      • React 이슈 (2)
      • Project 연습 (1)
      • Next.js (5)
    • Backend&Devops (33)
      • AWS (2)
      • Docker (9)
      • Jenkins (6)
      • Nginx (6)
      • Node.js (1)
      • ElasticSearch (5)
      • 프레임워크&아키텍처 (2)
      • 암호화 (0)
      • 기타 (2)
    • 알고리즘 (3)
    • C# (8)
      • WPF (8)
    • Java (51)
      • 순수 Java (18)
      • RDF&Jena (12)
      • RCP&GEF (9)
      • JMX (5)
      • JMapper (3)
      • 오류해결 (4)
    • Database (21)
      • RDBMS (9)
      • NoSQL (2)
      • TSDB (1)
      • GraphQL (1)
      • Hibernate (3)
      • 데이터베이스 이론 (4)
      • Redis (1)
    • 프로토콜 (11)
      • Netty (4)
      • gRPC (5)
      • 프로토콜 개념 (2)
    • Server (4)
      • Linux (4)
    • 2020 정보처리기사 필기 (43)
      • 목차 (1)
      • 기출문제 (1)
      • 1과목 - 소프트웨어 설계 (6)
      • 2과목 - 소프트웨어 개발 (7)
      • 3과목 - 데이터베이스 구축 (8)
      • 4과목 - 프로그래밍 언어 활용 (7)
      • 5과목 - 정보시스템 구축 관리 (10)
    • 2020 정보처리기사 실기 (31)
      • 목차 (4)
      • 기출예상문제 (19)
      • 실기요약 (8)
    • 빅데이터분석기사 필기 (4)
      • 목차 (0)
      • 필기 요약 (3)
    • 전기 공학 (1)
      • CIM (1)
    • 산업자동화시스템 (3)
      • SCADA (1)
      • OPC UA (2)
    • 디자인패턴 (1)
    • 휴지통 (0)

공지사항

  • 공지사항/포스팅 예정 항목

최근 댓글

최근 글

전체 방문자
오늘
어제

티스토리

hELLO · Designed By 정상우.
기은P

시간이 멈추는 장소

FrontEnd/React 기본

[React] React.js 강좌 16. useCallback

2022. 3. 8. 10:51
반응형

1. useCallback

useCallback이라는 Hook함수는 useMemo와 같이 함수를 Memozation하기 위해서 사용됩니다. useCallback은 첫번째 인자로 넘어온 함수를 두번째 인자로 넘어온 배열 내의 값이 변경될 때 까지 저장해 놓고 재사용 할 수 있게 해줍니다.

const callback = useCallback(함수, 배열);

만약, 어떤 React 컴포넌트 함수 안에 함수가 선언이 되어 있다면 이 함수는 해당 컴포넌트가 랜더링될 때 마다 새로운 함수가 생성됩니다.

const add = () => x + y;

하지만 useCallback()을 사용하면, 해당 컴포넌트가 랜더링되더라도 그 함수가 의존하는 값들이 바뀌지 않는 한 기존 함수를 계속해서 반환합니다. 즉, x 또는 y 값이 바뀌면 새로운 함수가 생성되어 add 변수에 할당되고, x와 y 값이 동일하다면 다음 랜더링 때 이 함수를 재사용합니다.

const add = useCallback(() => x + y, [x, y]);

 

 

 

2. 배열과 같이 사용

많은 React hook 함수들이 불필요한 작업을 줄이기 위해서 두 번째 인자로, 첫 번째 함수가 의존해야하는 배열을 받습니다.

예를 들어, useEffect() 함수는 두 번째 인자로 넘어온 의존 배열이 변경될 때만 첫 번째 인자로 넘어온 함수를 호출합니다.

예를 들어, 다음과 컴포넌트에서 API를 호출하는 코드는 fetchUser 함수가 변경될 때만 호출됩니다. 여기서 위에서 설명드린 자바스크립트가 함수의 동등성을 판단하는 방식 때문에 예상치 못한 무한 루프에 발생하게 됩니다. fetchUser는 함수이기 때문에, userId 값이 바뀌든 말든 컴포넌트가 랜더링될 때 마다 새로운 참조값으로 변경이 됩니다. 그러면 useEffect() 함수가 호출되어 user 상태값이 바뀌고 그러면 다시 랜더링이 되고 그럼 또 다시 useEffect() 함수가 호출되는 악순환이 반복됩니다.

import React, { useState, useEffect } from "react";

function Profile({ userId }) {
  const [user, setUser] = useState(null);

  const fetchUser = () =>
    fetch(`https://your-api.com/users/${userId}`)
      .then((response) => response.json())
      .then(({ user }) => user);

  useEffect(() => {
    fetchUser().then((user) => setUser(user));
  }, [fetchUser]);

  // ...
}

이와 같은 상황에서 useCallback() hook 함수를 이용하면 컴포넌트가 다시 랜더링되더라도 fetchUser 함수의 참조값을 동일하게 유지시킬 수 있습니다. 따라서 의도했던 대로, useEffect()에 넘어온 함수는 userId 값이 변경되지 않는 한 재호출 되지 않게 됩니다.

import React, { useState, useEffect } from "react";

function Profile({ userId }) {
  const [user, setUser] = useState(null);

  const fetchUser = useCallback(
    () =>
      fetch(`https://your-api.com/users/${userId}`)
        .then((response) => response.json())
        .then(({ user }) => user),
    [userId]
  );

  useEffect(() => {
    fetchUser().then((user) => setUser(user));
  }, [fetchUser]);

  // ...
}

 

 

3. 빈 배열과 의존성 배열

아래 코드에는 useCallback이 사용된 change와 insert라는 함수가 있습니다.

change에는 의존성 배열이 빈 배열이고, insert에는 의존성배열에 string과 stringList가 들어가 있습니다.

 

const change = useCallback((e) => {
	setString(e.target.value); 
}, []); 

const insert = useCallback((e) => {
	const newList = stringList.slice(); 
    	newList.push(string); 
    	setStringList(newList); 
}, [string, stringList]); 

 

둘의 차이가 무엇이길래, 하나는 의존성 배열이 비어있고, 하나는 값이 포함되어 있을까요?

 

change는 두번째 인자에 빈 배열을 주었기 때문에, 최초 렌더링 시에만 함수가 생성되고 이후에는 생성되지 않고, insert는 string과 stringList가 변경될 때만 함수를 재생성합니다. 

 

즉, insert의 경우 string과 stringList가 변하면 함수도 재생성되어야 하는데, 배열로 전달받은 두 state에 의존적이라고 볼수 있습니다.

하지만 change는 state를 사용하지 않고, 단지 state를 변경하는 것이므로, state에 의존적이지 않기 때문에 state가 변함에 따라 change 함수를 재생성해줄 필요는 없어서 빈 배열을 넣어주게 됩니다.

 

정리하자면, 해당 함수에서 state를 사용한다면, 말그대로 state에 의존하는 함수이므로 두번째 인자의 배열 안에 state를 추가해줘야 하고, state에 의존적이지 않은 함수라면 빈 배열로 넣어주면 됩니다.

 

 

 

 

참고

https://www.daleseo.com/react-hooks-use-callback/

반응형
저작자표시 변경금지 (새창열림)

'FrontEnd > React 기본' 카테고리의 다른 글

[React] React.js 강좌 18. useReducer  (0) 2022.03.08
[React] React.js 강좌 17. 불변성  (0) 2022.03.08
[React] React.js 강좌 15. useMemo  (0) 2022.03.08
[React] React.js 강좌 14. useEffect  (0) 2022.03.07
[React] React.js 강좌 13. useState  (0) 2022.03.07
    'FrontEnd/React 기본' 카테고리의 다른 글
    • [React] React.js 강좌 18. useReducer
    • [React] React.js 강좌 17. 불변성
    • [React] React.js 강좌 15. useMemo
    • [React] React.js 강좌 14. useEffect
    기은P
    기은P
    기은P의 블로그 일상과 개발 관련 포스팅 #React #Typescript #Next #Nest https://github.com/kimdongjang

    티스토리툴바