Skip to content

Conversation

@wantkdd
Copy link
Member

@wantkdd wantkdd commented May 19, 2025

πŸ“ λ―Έμ…˜ 번호

8μ£Όμ°¨ Misson 1, 2

πŸ“‹ κ΅¬ν˜„ 사항

  • Debounceλ₯Ό μ΄μš©ν•˜μ—¬ 검색 및 λ¬΄ν•œ 슀크둀 κ΅¬ν˜„
  • Throttling을 μ‚¬μš©ν•˜μ—¬ λ¬΄ν•œ 슀크둀 μ‹œ μ„±λŠ₯ κ°œμ„ 

πŸ“Ž μŠ€ν¬λ¦°μƒ·

image
image

βœ… 체크리슀트

  • Merge ν•˜λ €λŠ” λΈŒλžœμΉ˜κ°€ μ˜¬λ°”λ₯΄κ²Œ μ„€μ •λ˜μ–΄ μžˆλ‚˜μš”?
  • λ‘œμ»¬μ—μ„œ μ‹€ν–‰ν–ˆμ„ λ•Œ μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•Šλ‚˜μš”?
  • λΆˆν•„μš”ν•œ 주석이 μ œκ±°λ˜μ—ˆλ‚˜μš”?
  • μ½”λ“œ μŠ€νƒ€μΌμ΄ μΌκ΄€μ μΈκ°€μš”?

Copy link
Member

@hyesngy hyesngy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이번 μ£Ό μ›Œν¬λΆμ„ 톡해 React의 μ„±λŠ₯ μ΅œμ ν™” 기법인 debounce와 throttle을 μ μš©ν•΄λ΄€μŠ΅λ‹ˆλ‹€! 쉽지 μ•Šμ€ κ°œλ…μ΄μ§€λ§Œ λͺ¨λ‘ 잘 ν•΄λ‚΄μ…”μ„œ λŒ€λ‹¨ν•©λ‹ˆλ‹€! πŸ‘πŸ»πŸ‘πŸ»πŸ‘πŸ»

이런 μ΅œμ ν™” 기법듀은 μ‹€μ œ μ„œλΉ„μŠ€μ—μ„œ UXλ₯Ό 크게 ν–₯μƒμ‹œν‚€λŠ” μš”μ†Œμž…λ‹ˆλ‹€. μ•žμœΌλ‘œ μžˆμ„ 데λͺ¨λ°μ΄ ν”„λ‘œμ νŠΈμ—μ„œλ„ κΌ­ ν™œμš©ν•΄μ„œ κ΅¬ν˜„ν•΄λ³΄λ©΄ μ’‹κ² μŠ΅λ‹ˆλ‹€!πŸ‘πŸ»πŸ‘πŸ»πŸ‘πŸ»

Comment on lines 42 to 65
<div className="flex justify-end mb-6">
<div className="bg-gray-800 rounded-lg p-1 inline-flex">
<button
className={`px-4 py-2 rounded-md transition-all ${
order === 'desc'
? 'bg-pink-600 text-white'
: 'bg-transparent text-gray-300 hover:text-white'
}`}
onClick={() => setOrder('desc')}
>
μ΅œμ‹ μˆœ
</button>
<button
className={`px-4 py-2 rounded-md transition-all ${
order === 'asc'
? 'bg-pink-600 text-white'
: 'bg-transparent text-gray-300 hover:text-white'
}`}
onClick={() => setOrder('asc')}
>
였래된순
</button>
</div>
</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ν˜„μž¬ search-page와 home-pageμ—μ„œ μ •λ ¬ λ²„νŠΌ UIκ°€ μ€‘λ³΅λ˜κ³  μžˆλŠ”λ°, 이 뢀뢄을 λ³„λ„μ˜ SortButton μ»΄ν¬λ„ŒνŠΈλ‘œ λΆ„λ¦¬ν•˜λ©΄ μ½”λ“œ 쀑볡을 쀄이고 μΌκ΄€λœ UIλ₯Ό μœ μ§€ν•  수 μžˆμ„ 것 κ°™μŠ΅λ‹ˆλ‹€.

<LpCard key={lp.id} lp={lp} />
))}

{!isLoading && <LpCardSkeletonList count={20} />}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ν˜„μž¬ home-pageμ—μ„œ μŠ€μΌˆλ ˆν†€μ„ λ‘œλ”© 쀑이 아닐 λ•Œλ„ 항상 ν‘œμ‹œν•˜λ„λ‘ κ΅¬ν˜„λ˜μ–΄μžˆλŠ”λ°, μ˜λ„λœ λ™μž‘μΈμ§€ 이해가 κ°€μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μΆ”κ°€ 데이터λ₯Ό 뢈러올 λ•Œμ—λ§Œ, μŠ€μΌˆλ ˆν†€μ„ λ³΄μ—¬μ£ΌλŠ” 것이 μ‚¬μš©μžμ—κ²Œλ„ λͺ…ν™•ν•œ ν”Όλ“œλ°±μ„ 전달할 수 μžˆμ„ 것 κ°™μŠ΅λ‹ˆλ‹€.

일반적으둜 isFetchingNextPage μƒνƒœμ— 따라 μ‘°κ±΄λΆ€λ‘œ λ Œλ”λ§ν•˜μ—¬ μ˜ˆμ‹œλ‘œλŠ” {isFetchingNextPage && <LpCardSkeletonList count={20} />} 이런 μ‹μœΌλ‘œ μž‘μ„±ν•  수 μžˆμ„ 것 κ°™μŠ΅λ‹ˆλ‹€.

Comment on lines 10 to 24
const [search, setSearch] = useState('');
const [order, setOrder] = useState<'desc' | 'asc'>('desc');
const debouncedSearch = useDebounce(search, 500);
const { ref, inView } = useInView({ threshold: 0 });
const throttledInView = useThrottle(inView, 1000);

const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } =
useGetInfiniteLpList(10, order, debouncedSearch);

useEffect(() => {
if (throttledInView && hasNextPage && !isFetchingNextPage) {
fetchNextPage();
console.log('λ‹€μŒ νŽ˜μ΄μ§€ 호좜');
}
}, [throttledInView, hasNextPage, isFetchingNextPage, fetchNextPage]);
Copy link
Member

@hyesngy hyesngy May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2025-05-22.220636.mp4

ν˜„μž¬ λ¬΄ν•œ μŠ€ν¬λ‘€μ—μ„œ μ—¬λŸ¬ 번의 μš”μ²­μ΄ μ—°μ†μœΌλ‘œ λ°œμƒν•˜λŠ” λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€.

home-page와 search-page λͺ¨λ‘μ—μ„œ useEffect(() => { if (throttledInView && hasNextPage && !isFetchingNextPage) { fetchNextPage(); } }, [throttledInView, hasNextPage, isFetchingNextPage, fetchNextPage])둜 κ΅¬ν˜„λ˜μ–΄ μžˆλŠ”λ°, fetchNextPage() μ‹€ν–‰ ν›„ hasNextPageκ°€ μ—¬μ „νžˆ true이고 throttledInView도 계속 true둜 μœ μ§€λ˜λ©΄μ„œ μ—°μ†μ μœΌλ‘œ μš”μ²­μ΄ λ°œμƒν•˜κ³  μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

λ˜ν•œ, useInView({ threshold: 0 })둜 μ„€μ •λ˜μ–΄ μžˆμ–΄μ„œ νƒ€κ²Ÿ μš”μ†Œκ°€ 화면에 μ‘°κΈˆμ΄λΌλ„ 보이면 μ¦‰μ‹œ νŠΈλ¦¬κ±°λ©λ‹ˆλ‹€. λ˜ν•œ <div ref={ref} className="h-10 mt-4"></div> μš”μ†Œκ°€ 계속 화면에 λ…ΈμΆœλ˜μ–΄ μžˆμ–΄μ„œ μ§€μ†μ μœΌλ‘œ inViewκ°€ true μƒνƒœλ₯Ό μœ μ§€ν•˜κ²Œ λ©λ‹ˆλ‹€.

fetchNextPage() 호좜 직후 throttledInViewλ₯Ό μΌμ‹œμ μœΌλ‘œ false둜 λ§Œλ“€κ±°λ‚˜, μš”μ²­ μ™„λ£Œ ν›„μ—λ§Œ λ‹€μ‹œ 감지할 수 μžˆλ„λ‘ μƒνƒœ 관리λ₯Ό κ°œμ„ ν•΄μ•Ό ν•©λ‹ˆλ‹€. useCallback으둜 fetchNextPage ν•¨μˆ˜λ₯Ό κ°μ‹Έμ„œ λΆˆν•„μš”ν•œ μ˜μ‘΄μ„± 변경을 λ°©μ§€ν•˜λŠ” 것도 κ³ λ €ν•΄λ³Ό 수 μžˆμ„ 것 κ°™μŠ΅λ‹ˆλ‹€.

Intersection Observerμ—μ„œλ„ thresholdλ₯Ό 0.1 μ •λ„λ‘œ λ†’μ΄κ±°λ‚˜, rootMargin을 μŒμˆ˜κ°’μœΌλ‘œ μ„€μ •ν•˜μ—¬ μš”μ†Œκ°€ μ™„μ „νžˆ ν™”λ©΄ 쀑앙에 듀어왔을 λ•Œλ§Œ νŠΈλ¦¬κ±°λ˜λ„λ‘ μ‘°μ •ν•˜μ—¬ μ •ν™•ν•œ μ‹œμ μ—λ§Œ κ°μ§€λ˜λ„λ‘ κ°œμ„ ν•΄μ£Όμ„Έμš”!


const SearchPage: React.FC = () => {
const [search, setSearch] = useState('');
const [order, setOrder] = useState<'desc' | 'asc'>('desc');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ν˜„μž¬ HomePageμ—μ„œ ν•˜λ“œμ½”λ”©λœ "asc" | "desc" νƒ€μž…μ„ μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. PAGINATION_ORDER enum을 별도 νŒŒμΌμ— μ •μ˜ν•΄λ†¨μŒμ—λ„ λΆˆκ΅¬ν•˜κ³  λ¬Έμžμ—΄ λ¦¬ν„°λŸ΄ νƒ€μž…μ„ 직접 μ‚¬μš©ν•˜λ©΄ νƒ€μž… μ •μ˜κ°€ μ€‘λ³΅λ˜κ³  μœ μ§€λ³΄μˆ˜μ„±λ„ λ–¨μ–΄μ§‘λ‹ˆλ‹€.

μ •μ˜ν•΄λ‘” enum을 μ‚¬μš©ν•΄μ„œ useState<PAGINATION_ORDER>(PAGINATION_ORDER.DESC) 같은 ν˜•νƒœλ‘œ λ³€κ²½ν•˜λ©΄, νƒ€μž… μ•ˆμ •μ„±μ„ 높이고 μ½”λ“œ μœ μ§€λ³΄μˆ˜μ„±λ„ κ°œμ„ ν•  수 μžˆμ„ 것 κ°™μŠ΅λ‹ˆλ‹€!

@wantkdd wantkdd merged commit 4b5d1bc into main May 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants