Skip to content

Commit b082246

Browse files
committed
🚨 Fix synchronous state updates in Effect
1 parent fac9838 commit b082246

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

components/home/featured-jargon-carousel.tsx

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,36 @@ export default function FeaturedJargonCarousel({
3737
className?: string;
3838
}) {
3939
const [api, setApi] = useState<CarouselApi>();
40+
4041
const [canScrollPrev, setCanScrollPrev] = useState(false);
4142
const [canScrollNext, setCanScrollNext] = useState(false);
43+
44+
// Accept api so that it can be called while setting api
45+
const updateCanScroll = useCallback((api: CarouselApi) => {
46+
if (!api) return;
47+
setCanScrollPrev(api.canScrollPrev());
48+
setCanScrollNext(api.canScrollNext());
49+
}, []);
50+
4251
const [scrollProgress, setScrollProgress] = useState(0);
43-
const scrollbarRef = useRef<HTMLDivElement>(null);
44-
const isDraggingRef = useRef(false);
4552

46-
const onScroll = useCallback(() => {
53+
// Accept api so that it can be called while setting api
54+
const updateScrollProgress = useCallback((api: CarouselApi) => {
4755
if (!api) return;
4856
const progress = Math.max(0, Math.min(1, api.scrollProgress()));
4957
setScrollProgress(progress);
50-
}, [api]);
58+
}, []);
5159

60+
const handleSetApi = useCallback(
61+
(api: CarouselApi) => {
62+
setApi(api);
63+
updateCanScroll(api);
64+
updateScrollProgress(api);
65+
},
66+
[updateCanScroll, updateScrollProgress],
67+
);
68+
69+
const scrollbarRef = useRef<HTMLDivElement>(null);
5270
// Calculate scroll position from mouse X and scroll to that slide
5371
const scrollToPosition = useCallback(
5472
(clientX: number) => {
@@ -65,6 +83,7 @@ export default function FeaturedJargonCarousel({
6583
[api],
6684
);
6785

86+
const isDraggingRef = useRef(false);
6887
// Handle mouse down on scrollbar (start drag)
6988
const handleScrollbarMouseDown = useCallback(
7089
(e: React.MouseEvent<HTMLDivElement>) => {
@@ -99,14 +118,9 @@ export default function FeaturedJargonCarousel({
99118
return;
100119
}
101120

102-
setCanScrollPrev(api.canScrollPrev());
103-
setCanScrollNext(api.canScrollNext());
104-
onScroll();
121+
const onSelect = () => updateCanScroll(api);
122+
const onScroll = () => updateScrollProgress(api);
105123

106-
const onSelect = () => {
107-
setCanScrollPrev(api.canScrollPrev());
108-
setCanScrollNext(api.canScrollNext());
109-
};
110124
api.on("select", onSelect);
111125
api.on("scroll", onScroll);
112126
api.on("reInit", onScroll);
@@ -115,7 +129,7 @@ export default function FeaturedJargonCarousel({
115129
api.off("scroll", onScroll);
116130
api.off("reInit", onScroll);
117131
};
118-
}, [api, onScroll]);
132+
}, [api, updateCanScroll, updateScrollProgress]);
119133

120134
return (
121135
<div
@@ -132,7 +146,7 @@ export default function FeaturedJargonCarousel({
132146
<span className="text-amber-900 dark:text-amber-100">하이라이트</span>
133147
</h2>
134148
<Carousel
135-
setApi={setApi}
149+
setApi={handleSetApi}
136150
plugins={[autoplayPlugin, wheelGesturesPlugin]}
137151
className="relative w-full"
138152
onMouseEnter={autoplayPlugin.stop}

0 commit comments

Comments
 (0)