import { type DependencyList, type EffectCallback, useCallback, useEffect, useRef } from 'react';
/**
* @description useEffect를 좀 더 효과적으로 제어할 수 있는 훅입니다
* @reference https://github.com/toss/react-simplikit/blob/main/src/hooks/useConditionalEffect/useConditionalEffect.ts
*
* @param effect
* @param deps
* @param condition (prevDeps: T | undefined, currentDeps: T) => boolean
* - 이전 및 현재 의존성을 기반으로 효과를 실행할지 결정하는 함수예요.
* - 초기 렌더링 시, prevDeps는 undefined일 거예요. condition 함수는 이 경우를 처리해야 해요.
* - 초기 렌더링 시 효과를 실행하려면, prevDeps가 undefined일 때 true를 반환하면 돼요.
* - 초기 렌더링 시 효과를 실행하고 싶지 않다면, prevDeps가 undefined일 때 false를 반환하면 돼요.
*/
export function useConditionalEffect<T extends DependencyList>(
effect: EffectCallback,
deps: T,
condition: (prevDeps: T | undefined, currentDeps: T) => boolean,
): void {
const prevDepsRef = useRef<T | undefined>(undefined);
const memoizedCondition = useCallback(condition, deps);
if (deps.length === 0) {
console.warn(
'useConditionalEffect received an empty dependency array. ' +
'This may indicate missing dependencies and could lead to unexpected behavior.',
);
}
const shouldRun = memoizedCondition(prevDepsRef.current, deps);
useEffect(() => {
if (shouldRun) {
const cleanup = effect();
prevDepsRef.current = deps;
return cleanup;
}
prevDepsRef.current = deps;
}, deps);
}
useConditionalEffect
의존성 및 조건 기반으로 useEffect 동작 여부를 결정하는 훅입니다
4