[React] useSyncExternalStore
React 18에서는 외부 데이터 소스와 React 상태를 동기화하기 위한 새로운 훅인 useSyncExternalStore가 도입되었습니다.
이는 주로 React 컴포넌트가 브라우저 API나 서드파티 라이브러리와 같은 외부 데이터 소스에 구독해야 하는 경우에 유용합니다.
기존 접근법: useEffect 사용
전통적으로, useEffect 훅을 사용하여 외부 데이터 소스를 구독하고 상태를 업데이트하는 방법이 일반적이었습니다.
예를 들어, 사용자의 온라인 상태를 추적하는 코드는 다음과 같습니다:
import { useState, useEffect } from 'react';
function useOnlineStatus() {
const [isOnline, setIsOnline] = useState(true);
useEffect(() => {
function updateState() {
setIsOnline(navigator.onLine);
}
updateState();
window.addEventListener('online', updateState);
window.addEventListener('offline', updateState);
return () => {
window.removeEventListener('online', updateState);
window.removeEventListener('offline', updateState);
};
}, []);
return isOnline;
}
function ChatIndicator() {
const isOnline = useOnlineStatus();
return (
<div>
{isOnline ? '🟢 Online' : '🔴 Offline'}
</div>
);
}
이 방법은 잘 작동하지만, 상태를 수동으로 동기화해야 하고, 코드가 복잡해질 수 있습니다.
새로운 접근법: useSyncExternalStore 사용
useSyncExternalStore는 외부 데이터 소스에 구독하는 더 깔끔하고 효율적인 방법을 제공합니다. 이 훅은 React 상태와 외부 데이터를 동기화하는 데 최적화되어 있습니다.
useSyncExternalStore 사용 예제
Step 1: 구독 함수 작성
먼저, 온라인 상태 변화를 구독하는 함수를 작성합니다.
이 함수는 콜백을 받아 이벤트 리스너를 등록하고, 정리(cleanup) 함수로 이벤트 리스너를 제거합니다.
function subscribe(callback) {
window.addEventListener('online', callback);
window.addEventListener('offline', callback);
return () => {
window.removeEventListener('online', callback);
window.removeEventListener('offline', callback);
};
}
Step 2: useSyncExternalStore 훅 사용
다음으로, useSyncExternalStore 훅을 사용하여 온라인 상태를 추적하는 커스텀 훅을 작성합니다.
import { useSyncExternalStore } from 'react';
function useOnlineStatus() {
return useSyncExternalStore(
subscribe, // 구독 함수
() => navigator.onLine, // 클라이언트에서 현재 값 가져오기
() => true // 서버에서 초기 값 가져오기 (기본 값)
);
}
Step 3: 컴포넌트에서 사용
이제 이 커스텀 훅을 컴포넌트에서 사용하여 온라인 상태를 표시합니다.
import React from 'react';
function ChatIndicator() {
const isOnline = useOnlineStatus();
return (
<div>
{isOnline ? '🟢 Online' : '🔴 Offline'}
</div>
);
}
export default ChatIndicator;
최종코드
import { useState, useEffect } from 'react';
function useOnlineStatus() {
const [isOnline, setIsOnline] = useState(true);
useEffect(() => {
function updateState() {
setIsOnline(navigator.onLine);
}
updateState();
window.addEventListener('online', updateState);
window.addEventListener('offline', updateState);
return () => {
window.removeEventListener('online', updateState);
window.removeEventListener('offline', updateState);
};
}, []);
return isOnline;
}
function ChatIndicator() {
const isOnline = useOnlineStatus();
return (
<div>
{isOnline ? '🟢 Online' : '🔴 Offline'}
</div>
);
}
장점과 단점
장점
- 간결성: useSyncExternalStore를 사용하면 구독 로직이 간결하고 명확해집니다.
- 효율성: 이 훅은 외부 데이터와 React 상태를 효율적으로 동기화합니다.
- 최적화: 상태 업데이트를 최적화하여 불필요한 렌더링을 방지합니다.
단점
- 새로운 개념: 기존의 useEffect 패턴에 익숙한 개발자에게는 새로운 개념을 배우는 데 시간이 걸릴 수 있습니다.
- 제한적인 사용 사례: 모든 외부 데이터 구독에 적용되지는 않을 수 있습니다. 특정한 경우에 더 적합합니다.
- 특정한 경우: 외부 데이터 소스와의 동기화가 필요한 경우 (브라우저 api 구독, 온라인 상태 추적 , 서드파티 라이브러리구독 등)
요약
useSyncExternalStore는 React 18에서 도입된 외부 데이터 소스에 구독하기 위한 새로운 훅입니다.
이를 사용하면 외부 데이터와 React 상태를 더 간결하고 효율적으로 동기화할 수 있습니다.
기존의 useEffect 패턴과 비교하여 장점이 많으므로, 외부 데이터 소스와의 구독이 필요한 경우 이 훅을 사용하는 것을 고려해보세요.
참조:
https://react.dev/learn/you-might-not-need-an-effect
You Might Not Need an Effect – React
The library for web and native user interfaces
react.dev
'react.js' 카테고리의 다른 글
[React] useEffect 의존성 제거하기 (0) | 2024.06.10 |
---|---|
[React] useEffectEvent hook (0) | 2024.06.10 |
[React] Props 변경 시 상태 초기화하기 (not UseEffect, but Key) (0) | 2024.06.09 |
[React] react에서의 Side Effect (0) | 2024.06.09 |
[React] flushSync (0) | 2024.06.08 |
댓글