From 357abe3641a50c781fb8cfb3e5f4b66ac424a88f Mon Sep 17 00:00:00 2001 From: evan-moon Date: Sun, 22 Aug 2021 14:16:37 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat(react):=20useCombinedRefs,=20useScroll?= =?UTF-8?q?Event=20=ED=9B=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react/src/hooks/useCombinedRef.ts | 31 ++++++++++++++++++++++ packages/react/src/hooks/useScrollEvent.ts | 20 ++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 packages/react/src/hooks/useCombinedRef.ts create mode 100644 packages/react/src/hooks/useScrollEvent.ts diff --git a/packages/react/src/hooks/useCombinedRef.ts b/packages/react/src/hooks/useCombinedRef.ts new file mode 100644 index 00000000..17ae12c4 --- /dev/null +++ b/packages/react/src/hooks/useCombinedRef.ts @@ -0,0 +1,31 @@ +import { Ref, useCallback, MutableRefObject, RefCallback } from 'react'; + +/** + * 여러 개의 ref를 합칠 수 있는 훅입니다. + * @example + * const Foo = forwardRef((props, fowardedRef) => { + * const ref = useRef(); + * const combinedRef = useCombinedRefs(fowardedRef, ref2); + * + * // div가 업데이트되면 ref, fowardedRef 둘 다 업데이트 됨 + * return
+ * }); + */ +export default function useCombinedRefs( + ...refs: Array | RefCallback> +): RefCallback { + const combinedRef = useCallback( + (value: T) => { + refs.forEach((ref) => { + if (typeof ref === 'function') { + ref(value); + } else if (ref != null) { + (ref as MutableRefObject).current = value; + } + }); + }, + [refs] + ); + + return combinedRef; +} diff --git a/packages/react/src/hooks/useScrollEvent.ts b/packages/react/src/hooks/useScrollEvent.ts new file mode 100644 index 00000000..d55c9519 --- /dev/null +++ b/packages/react/src/hooks/useScrollEvent.ts @@ -0,0 +1,20 @@ +import { RefObject, useEffect } from 'react'; + +/** + * 컴포넌트에 스크롤 이벤트를 추가하는 hook입니다. + * useEffect dependency로 hook의 인자인 ref, scrollCallback을 포함하고 있어 + * ref, scrollCallback의 레퍼런스가 변경 될 때마다 스크롤 이벤트가 바인딩됩니다. + * 이 부분을 참고하셔서 성능이슈가 발생하지 않도록 잘 관리해주세요. + */ +const useScrollEvent = (ref: RefObject, scrollCallback: () => void) => { + useEffect(() => { + if (ref.current === null) { + return; + } + + ref.current.addEventListener('scroll', scrollCallback, { passive: true }); + return () => ref.current?.removeEventListener('scroll', scrollCallback); + }, [ref, scrollCallback]); +}; + +export default useScrollEvent; From 9b25ed7c4b65d779c74f3936946859b2a41a0f0b Mon Sep 17 00:00:00 2001 From: evan-moon Date: Sun, 22 Aug 2021 15:34:34 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=EC=9D=98=EB=AF=B8=EC=97=86=EB=8A=94=20RefC?= =?UTF-8?q?allback=20=ED=83=80=EC=9E=85=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react/src/hooks/useCombinedRef.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/react/src/hooks/useCombinedRef.ts b/packages/react/src/hooks/useCombinedRef.ts index 17ae12c4..6733a3ce 100644 --- a/packages/react/src/hooks/useCombinedRef.ts +++ b/packages/react/src/hooks/useCombinedRef.ts @@ -11,9 +11,7 @@ import { Ref, useCallback, MutableRefObject, RefCallback } from 'react'; * return
* }); */ -export default function useCombinedRefs( - ...refs: Array | RefCallback> -): RefCallback { +export default function useCombinedRefs(...refs: Array>): RefCallback { const combinedRef = useCallback( (value: T) => { refs.forEach((ref) => { From 600efbec1b1134de16d679af73f5f8a6dbb8cc80 Mon Sep 17 00:00:00 2001 From: evan-moon Date: Sun, 22 Aug 2021 15:35:39 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=EC=98=88=EC=8B=9C=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react/src/hooks/useCombinedRef.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/hooks/useCombinedRef.ts b/packages/react/src/hooks/useCombinedRef.ts index 6733a3ce..53cdb42b 100644 --- a/packages/react/src/hooks/useCombinedRef.ts +++ b/packages/react/src/hooks/useCombinedRef.ts @@ -5,7 +5,7 @@ import { Ref, useCallback, MutableRefObject, RefCallback } from 'react'; * @example * const Foo = forwardRef((props, fowardedRef) => { * const ref = useRef(); - * const combinedRef = useCombinedRefs(fowardedRef, ref2); + * const combinedRef = useCombinedRefs(fowardedRef, ref); * * // div가 업데이트되면 ref, fowardedRef 둘 다 업데이트 됨 * return