Skip to content

Commit

Permalink
fix: useIntersectionObserver 기능 개선 (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
ssi02014 authored Apr 25, 2024
1 parent f444ae9 commit 03b3d3b
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 66 deletions.
5 changes: 5 additions & 0 deletions .changeset/gold-cheetahs-clap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modern-kit/react': patch
---

fix: useIntersectionObserver 기능 개선
8 changes: 0 additions & 8 deletions docs/docs/react/components/InView.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@ import { InView } from '@modern-kit/react';

## Interface
```tsx
interface UseIntersectionObserverProps {
action: (entry: IntersectionObserverEntry) => void;
calledOnce?: boolean;
threshold?: number | number[];
root?: Document | Element | null;
rootMargin?: string;
}

type InViewProps = React.ComponentProps<'div'> & UseIntersectionObserverProps;

const InView: React.ForwardRefExoticComponent<
Expand Down
9 changes: 4 additions & 5 deletions docs/docs/react/components/LazyImage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ Intersection Observer Option을 설정할 수 있습니다.(하단 `Note` 참고

## Interface
```tsx
interface LazyImageProps extends React.ComponentProps<'img'> {
interface LazyImageProps
extends React.ComponentProps<'img'>,
IntersectionObserverInit {
src: string;
threshold?: number | number[]; // default: 0
root?: Document | Element | null; // default: null
rootMargin?: string; // default: '0px 0px 0px 0px'
}

const LazyImage: React.ForwardRefExoticComponent<Omit<LazyImageProps, "ref"> & React.RefAttributes<HTMLDivElement>>
const LazyImage: React.ForwardRefExoticComponent<Omit<LazyImageProps, "ref"> & React.RefAttributes<HTMLImageElement>>
```
## Usage
Expand Down
19 changes: 8 additions & 11 deletions docs/docs/react/hooks/useIntersectionObserver.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,18 @@ Intersection Observer Option을 설정할 수 있습니다.(하단 `Note` 참고

## Interface
```tsx
interface UseIntersectionObserverProps {
interface UseIntersectionObserverProps extends IntersectionObserverInit {
action: (entry: IntersectionObserverEntry) => void;
calledOnce?: boolean;
threshold?: number | number[];
root?: Document | Element | null;
rootMargin?: string;
}

const useIntersectionObserver: <T extends HTMLElement>({
action,
calledOnce,
root,
threshold,
rootMargin
}: UseIntersectionObserverProps) => React.RefObject<T>
const useIntersectionObserver: <T extends HTMLElement>({
action,
calledOnce,
root,
threshold,
rootMargin,
}: UseIntersectionObserverProps) => (node: T) => void;
```

## Usage
Expand Down
7 changes: 3 additions & 4 deletions packages/react/src/components/LazyImage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import React, { CSSProperties, forwardRef, useMemo } from 'react';
import { useIntersectionObserver } from '../../hooks/useIntersectionObserver';
import { useMergeRefs } from '../../hooks/useMergeRefs';

interface LazyImageProps extends React.ComponentProps<'img'> {
interface LazyImageProps
extends React.ComponentProps<'img'>,
IntersectionObserverInit {
src: string;
threshold?: number | number[];
root?: Document | Element | null;
rootMargin?: string;
}

export const LazyImage = forwardRef<HTMLImageElement, LazyImageProps>(
Expand Down
64 changes: 26 additions & 38 deletions packages/react/src/hooks/useIntersectionObserver/index.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,54 @@
import { useCallback, useEffect, useRef } from 'react';
import { useRef } from 'react';
import { usePreservedCallback } from '../usePreservedCallback';
import { noop } from '@modern-kit/utils';

export interface UseIntersectionObserverProps {
export interface UseIntersectionObserverProps extends IntersectionObserverInit {
action: (entry: IntersectionObserverEntry) => void;
calledOnce?: boolean;
threshold?: number | number[];
root?: Document | Element | null;
rootMargin?: string;
}

export const useIntersectionObserver = <T extends HTMLElement>({
action,
calledOnce = false,
root = null,
threshold = 0,
threshold = [0],
rootMargin = '0px 0px 0px 0px',
}: UseIntersectionObserverProps) => {
const ref = useRef<T>(null);
const callbackAction = usePreservedCallback(action);
const intersectionObserverRef = useRef<IntersectionObserver | null>(null);

const observerCallback = useCallback(
const callbackAction = usePreservedCallback(action ?? noop);

const observerAction = usePreservedCallback(
([entry]: IntersectionObserverEntry[], observer: IntersectionObserver) => {
if (entry) {
if (entry.isIntersecting) {
const targetElement = entry.target as HTMLElement;
if (entry && entry.isIntersecting) {
const targetElement = entry.target as T;

if (callbackAction) {
callbackAction(entry);
}
if (callbackAction) {
callbackAction(entry);
}

if (calledOnce) {
observer.unobserve(targetElement);
}
if (calledOnce) {
observer.unobserve(targetElement);
}
}
},
[callbackAction, calledOnce]
);

useEffect(() => {
const targetElement = ref.current;

if (typeof IntersectionObserver === 'undefined') {
return;
}
);

if (!targetElement) {
return;
const targetRef = usePreservedCallback((node: T) => {
if (intersectionObserverRef.current) {
intersectionObserverRef.current.disconnect();
}

const observer = new IntersectionObserver(observerCallback, {
intersectionObserverRef.current = new IntersectionObserver(observerAction, {
root,
rootMargin,
threshold,
rootMargin,
});

observer.observe(targetElement);

return () => {
observer.unobserve(targetElement);
};
}, [root, threshold, rootMargin, observerCallback]);
if (node) {
intersectionObserverRef.current.observe(node);
}
});

return ref;
return targetRef;
};

0 comments on commit 03b3d3b

Please sign in to comment.