React의 데이터 가져오기 후크 비교

React에서 후크는 컴포넌트 내에서 부수 효과를 효율적으로 관리하는 중요한 도구입니다. 그중에서도 useEffect, useLayoutEffect, useEffectEvent는 가장 흔하게 사용되는 후크들입니다. 이들은 각각 고유한 사용 사례를 가지고 있기 때문에, 주어진 상황에 가장 적합한 후크를 선택하는 것이 중요합니다.

useEffect 후크

useEffect는 React의 기본적인 후크 중 하나로, 함수형 컴포넌트 내부에서 DOM 조작, 비동기 작업, 데이터 가져오기 등의 부수 효과를 수행할 수 있게 해줍니다. 이 후크는 두 가지 인수를 받는데, 하나는 실행할 부수 효과 함수이고 다른 하나는 종속성 배열입니다.

부수 효과 함수에는 실제 부수 효과를 수행하는 코드가 들어 있으며, 종속성 배열은 이 함수가 언제 실행되어야 하는지를 결정합니다. 종속성 배열이 비어 있을 경우 부수 효과 함수는 컴포넌트가 처음 렌더링될 때 단 한 번 실행됩니다. 만약 종속성 배열에 값이 있을 경우, 해당 값들이 변경될 때마다 부수 효과 함수가 실행됩니다.

다음은 useEffect 후크를 사용하여 데이터를 가져오는 간단한 예시입니다.

 import React from "react";

function App() {
const [data, setData] = React.useState([]);

React.useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((data) => setData(data));
}, []);

return (
<div className="app">
{data.map((item) => (
<div key={item.id}>{item.title}</div>
))}
</div>
);
}

export default App;

이 코드에서는 useEffect 후크를 사용하여 외부 API에서 데이터를 가져와 화면에 표시하는 방법을 보여줍니다. 부수 효과 함수는 JSONPlaceholder API로부터 데이터를 가져오고, 받은 JSON 응답을 파싱하여 data 상태에 저장합니다. 그런 다음, App 컴포넌트는 data 상태에 저장된 각 항목의 title 속성을 렌더링합니다.

useEffect 후크의 특징

  • 비동기 작업 친화적: 비동기 작업을 자연스럽게 처리할 수 있어 데이터 가져오기에 매우 적합합니다.
  • 렌더링 후 실행: useEffect 후크는 컴포넌트 렌더링이 완료된 후에 부수 효과를 실행하여 UI를 블로킹하지 않도록 합니다.
  • 정리 기능: 함수를 반환하여 정리 작업을 수행하는 방법을 제공합니다. 이는 특히 리스너나 구독 작업을 관리할 때 유용합니다.

useLayoutEffect 후크

useLayoutEffect 후크는 useEffect와 유사하지만, DOM 변경이 완료된 직후 동기적으로 실행된다는 차이점이 있습니다. 즉, 브라우저가 화면을 업데이트하기 전에 실행되므로, DOM 레이아웃과 스타일에 대한 세밀한 제어가 필요한 작업에 적합합니다. 예를 들어, 요소의 크기를 측정하거나, 크기를 조정하거나, 위치 애니메이션을 처리하는 데 사용할 수 있습니다.

아래는 useLayoutEffect 후크를 사용하여 버튼 요소의 너비를 변경하는 예시입니다.

 import React from "react";

function App() {
const button = React.useRef();

React.useLayoutEffect(() => {
const { width } = button.current.getBoundingClientRect();

button.current.style.width = `${width + 12}px`;
}, []);

return (
<div className="app">
<button ref={button}>Click Me</button>
</div>
);
}

export default App;

위 코드에서는 useLayoutEffect 후크를 사용하여 버튼 요소의 너비를 12픽셀만큼 늘리는 방법을 보여줍니다. 이렇게 하면 브라우저가 화면에 버튼을 그리기 전에 버튼의 너비가 늘어나게 됩니다.

useLayoutEffect 후크의 특징

  • 동기적 실행: 동기적으로 실행되므로, 내부 작업이 많을 경우 UI를 차단할 가능성이 있습니다.
  • DOM 읽기/쓰기: 브라우저가 다시 그리기 전에 변경이 필요한 경우, DOM에서 직접 읽고 쓰는 데 적합합니다.

useEffectEvent 후크

useEffectEvent 후크는 useEffect 후크의 종속성 문제를 해결하기 위해 도입된 실험적인 React 후크입니다. useEffect를 사용해 본 경험이 있다면, 종속성 배열을 관리하는 것이 때로는 복잡하고 어려울 수 있다는 것을 알 수 있습니다. 종종 불필요하게 더 많은 값을 종속성 배열에 추가해야 하는 상황도 발생합니다.

다음 코드는 종속성 문제의 예시입니다.

 import React from "react";

function App() {
const connect = (url) => {
// ...
};

const logConnection = (message, loginOptions) => {
// ...
};

const onConnected = (url, loginOptions) => {
logConnection(`Connected to ${url}`, loginOptions);
};

React.useEffect(() => {
const device = connect(url);
device.onConnected(() => {
onConnected(url);
});

return () => {
device.disconnect();
};
}, [url, onConnected]);

return <div></div>;
}

export default App;

이 코드에서는 외부 서비스에 대한 연결을 관리하는 App 컴포넌트를 보여줍니다. connect 함수는 지정된 URL에 연결하고, logConnection 함수는 연결 정보를 기록하며, onConnected 함수는 장치가 연결되었을 때 성공적인 연결 메시지를 기록합니다. useEffect 후크는 connect 함수를 호출하고, 장치에서 onConnected 이벤트가 발생했을 때 실행될 콜백 함수를 설정합니다. 이 콜백은 연결 메시지를 기록합니다. 또한, 컴포넌트가 마운트 해제될 때 실행되는 정리 함수를 반환합니다. 이 정리 함수는 장치 연결을 끊는 역할을 합니다.

종속성 배열에는 url 변수와 onConnected 함수가 있습니다. App 컴포넌트는 매번 렌더링될 때마다 onConnected 함수를 새로 생성합니다. 이로 인해 useEffect 함수가 루프에 빠져 컴포넌트가 계속해서 다시 렌더링되는 문제가 발생합니다.

이러한 useEffect 루프 문제를 해결하는 방법은 여러 가지가 있지만, 종속성 배열에 불필요한 값을 추가하지 않고 문제를 해결하는 가장 효율적인 방법 중 하나는 useEffectEvent 후크를 사용하는 것입니다.

 import React from "react";

function App() {
const connect = (url) => {
// ...
};

const logConnection = (message, loginOptions) => {
// ...
};

const onConnected = React.useEffectEvent((url, loginOptions) => {
logConnection(`Connected to ${url}`, loginOptions);
});

React.useEffect(() => {
const device = connect(url);
device.onConnected(() => {
onConnected(url);
});

return () => {
device.disconnect();
};
}, [url]);

return <div></div>;
}
export default App;

onConnected 함수를 useEffectEvent 후크로 감싸면, useEffectEvent 후크는 메시지 및 loginOptions 매개변수를 useEffect 후크에 전달하기 전에 항상 최신 값을 읽을 수 있게 합니다. 즉, useEffectonConnected 함수나 전달되는 값에 의존할 필요가 없게 됩니다.

useEffectEvent 후크는 useEffect에서 종속성으로 사용하고 싶지 않은 다른 값이 필요한 이벤트를 트리거하는 경우에 특히 유용합니다.

useEffectEvent 후크의 특징

  • 이벤트 기반 부수 효과에 적합합니다.
  • useEffectEvent 후크는 onClick, onChange와 같은 이벤트 핸들러에서는 작동하지 않습니다.

useEffectEvent 후크는 아직 실험적인 기능이며, React 18 버전에서는 사용할 수 없습니다.

어떤 후크를 언제 사용해야 할까요?

각 데이터 가져오기 후크는 다양한 상황에 적합합니다.

  • 데이터 가져오기: useEffect 후크가 가장 적합한 선택입니다.
  • 직접적인 DOM 조작: 렌더링 전에 DOM을 동기적으로 변경해야 할 경우, useLayoutEffect 후크를 사용하세요.
  • 가벼운 작업: UI를 차단할 위험이 없는 작업의 경우 useEffect 후크를 사용하면 됩니다.
  • 이벤트 기반 부수 효과: useEffectEvent 후크로 이벤트를 감싸고 useEffect 후크를 사용하여 부수 효과를 실행합니다.

부수 효과를 효율적으로 처리하기

React 후크는 다양한 가능성을 열어줍니다. useEffect, useLayoutEffect, useEffectEvent 후크 간의 차이점을 정확히 이해하는 것은 부수 효과 및 DOM 조작을 처리하는 방법에 큰 영향을 줄 수 있습니다. 사용자 친화적인 애플리케이션을 만들기 위해 이러한 후크의 특정 요구 사항과 의미를 고려하는 것이 중요합니다.