inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

처음 만난 리액트(React)

useEffect() 안에 함수를 정의하는 이유가 무엇인가요?

해결된 질문

2179

양우진

작성한 질문수 1

1

안녕하세요, 소플님.

챕터 7 나만의 훅 만들기를 공부하다가 궁금한 점이 있어서 질문드립니다.

 

228쪽 커스텀 훅 추출하기 예제 코드에서

function useUserStatus(userId) {
  //...

  useEffect(() => {
    function handleStatusChange(status) {
      //...
    }

    //...
  })

  //...
}

이런 식으로 useEffect 안에 handleStatusChange 함수를 정의하셨는데,

useUserStatus 바로 아래에 정의하지 않고 useEffect 안에 정의하신 이유가 있을까요?

어떤 상황에서 useEffect 안에 함수를 정의해야 하는 것인지 궁금합니다.

 

감사합니다.

react

답변 1

1

Inje Lee (소플)

안녕하세요, 소플입니다.

handleStatusChange() 라는 함수는 useEffect() 훅 내부에서만 사용하는 함수이기 때문에,
useEffect() 훅의 내부에서 선언해서 사용한 것입니다.

책의 214p에서 useEffect() 훅을 설명할 때 나온 부분의 코드처럼,
아래와 같이 useEffect() 훅의 바깥에서 선언해서 사용할 수도 있지만,
이렇게 하게 되면 컴포넌트가 재렌더링 될 때마다 매번 함수가 새로 정의됩니다.

import { useState, useEffect } from 'react';

function useUserStatus(props) {
    const [isOnline, setIsOnline] = useState(null);

    function handleStatusChange(status) {
        setIsOnline(status.isOnline);
    }

    useEffect(() => {
        ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
        return () => {
            ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
        };
    });

    return isOnline;
}

export default useUserStatus;

그래서 불필요한 함수 재정의를 방지하고 함수의 scope를 최소화 시키기 위해서
useEffect() 훅 내부에 함수를 선언하는 것이라고 보면 됩니다.

물론 위 코드의 useEffect() 훅은 의존성 배열이 없기 때문에 매 렌더링마다 Effect 함수가 실행됩니다.
(클래스 컴포넌트의 componentDidUpdate()를 생각하면 됩니다.)

 

그리고 추가로 useEffect() 훅 내부에 함수를 정의하는 경우는 비동기 호출을 하는 경우가 있습니다.

예를 들어, 컴포넌트가 마운트 된 이후에 서버로부터 데이터를 받아오고자 하는 경우,
일반적으로 아래와 같이 시도해보게 됩니다.

import { useEffect } from 'react';

function MyComponent(props) {
    useEffect(async () => {
        const response = await ServerAPI.fetchUserData();

        // Do something with response
        // ...
    }, []);

    return <div>Hello, MyComponent!</div>;
}

export default MyComponent;

하지만 위와 같이 코드를 작성하면 아래와 같은 경고 메시지가 뜨게 됩니다.

Effect callbacks are synchronous to prevent race conditions. Put the async function inside:

이 말은 Effect 함수는 race condition을 방지하기 위해서 비동기가 아닌 동기 방식으로 실행되기 때문에,
Effect 함수에 async를 붙이면 안 된다는 것입니다.

그래서 보통은 아래 코드와 같이 useEffect() 훅 내부에 비동기 함수를 정의하고,
정의한 함수를 호출하는 형태로 사용합니다.

import { useEffect } from 'react';

function MyComponent(props) {
    useEffect(() => {
        async function fetchUserData(status) {
            const response = await ServerAPI.fetchUserData();

            // Do something with response
            // ...
        }

        fetchUserData();
    }, []);

    return <div>Hello, MyComponent!</div>;
}

export default MyComponent;

 

개발하면서 훅을 여러가지 형태로 사용해보고 console.log()를 출력해서 결과도 보시면,
더 빠르게 이해하실 수 있을 것입니다.

학습 중 추가로 더 궁금한 부분은 언제든지 질문해주시기 바랍니다!

감사합니다.

0

양우진

궁금했던 점이 완전히 해결되었습니다!

자세한 설명 감사합니다..!

강의가 삭제되었다고 합니다

0

109

1

이거 왜 존재하지 않는다고 뜨는건가요

0

135

1

존재하지 않는 수업이라고 떠요

0

184

1

안드로이드 에뮬레이터 오류

0

100

1

교재 구입해서 강의 들으려고 하는데 커리큘럼이 없어졌어요.

0

128

1

prevIsConfiromed 질문

1

142

2

chapter14 잘이해가 되지않습니다..

1

136

2

2025년 3월 리액트버전

1

204

2

npm 설치 오류

1

178

1

chapter_07 콘솔로그 질문드려요~!

1

128

2

안녕하세요 미니블로그 실습 질문드립니다.

1

179

3

에러가 떠요

1

219

3

Chapter6 질문 드립니다

1

210

2

실습 코드 있을까요?

1

207

2

상태가 업데이트될때 컴포넌트 최상단의 console.log 코드가 두번 실행되는 이유가 궁금합니다.

1

233

2

npx create-react-app my-app 명령어 입력이 잘못된 것 같습니다

0

308

3

이름과 코멘트 줄바꿈이 안 됩니다.

0

142

1

버튼이 안 뜹니다

0

305

2

npx create-react-app my-app

1

471

2

jsx 코드 작성해보기에서 index.js 수정 후 에러 뜹니다.

1

377

3

Chapter_05 터미널, 리액트 에러

0

194

2

npx create-react-app my-app 명령어 반응없음

1

433

3

import 코드 에러

1

215

1

백틱

1

122

1