해결된 질문
작성
·
1.8K
1
안녕하세요, 소플님.
챕터 7 나만의 훅 만들기를 공부하다가 궁금한 점이 있어서 질문드립니다.
228쪽 커스텀 훅 추출하기 예제 코드에서
function useUserStatus(userId) {
//...
useEffect(() => {
function handleStatusChange(status) {
//...
}
//...
})
//...
}
이런 식으로 useEffect 안에 handleStatusChange
함수를 정의하셨는데,
useUserStatus
바로 아래에 정의하지 않고 useEffect 안에 정의하신 이유가 있을까요?
어떤 상황에서 useEffect 안에 함수를 정의해야 하는 것인지 궁금합니다.
감사합니다.
답변 1
1
안녕하세요, 소플입니다.
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()
를 출력해서 결과도 보시면,
더 빠르게 이해하실 수 있을 것입니다.
학습 중 추가로 더 궁금한 부분은 언제든지 질문해주시기 바랍니다!
감사합니다.
궁금했던 점이 완전히 해결되었습니다!
자세한 설명 감사합니다..!