Skip to content

Commit 5e2c165

Browse files
authored
Merge pull request #159 from Room-Fit/fix#144
Fix#144: 프로필 등록 모달이 제대로 열리지 않는 현상 수정
2 parents 8523d0b + a8a2d7d commit 5e2c165

File tree

2 files changed

+77
-31
lines changed

2 files changed

+77
-31
lines changed

src/shared/components/Modal/Modal.tsx

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import React, { useEffect } from "react";
1+
import React from "react";
22
import { createPortal } from "react-dom";
33

44
import { useModal } from "@/shared/components/Modal/useModal";
5-
import { useInitialStyle } from "@/shared/hooks";
5+
import { useOnMountAnimation } from "@/shared/hooks/useOnMountAnimation";
66
import { cn } from "@/shared/lib";
77

88
export interface ModalProps {
@@ -33,18 +33,18 @@ const Wrapper = ({ children }: { children?: React.ReactNode }) => {
3333
const Overlay = () => {
3434
const { closeModal } = useModal();
3535

36-
const { ref } = useInitialStyle<HTMLDivElement>({
37-
opacity: "0",
38-
transition: "all 200ms ease-in-out",
36+
const { ref } = useOnMountAnimation<HTMLDivElement>({
37+
initialStyles: {
38+
opacity: "0",
39+
},
40+
animationStyles: {
41+
opacity: "1",
42+
},
43+
duration: 200,
44+
delay: 0,
45+
timingFunction: "ease-in-out",
3946
});
4047

41-
useEffect(() => {
42-
const element = ref.current;
43-
if (!element) return;
44-
45-
element.style.opacity = "1";
46-
}, [ref]);
47-
4848
return (
4949
<div
5050
ref={ref}
@@ -55,27 +55,21 @@ const Overlay = () => {
5555
};
5656

5757
const Container = ({ children }: { children?: React.ReactNode }) => {
58-
const { isOpen } = useModal();
59-
60-
const { ref } = useInitialStyle<HTMLDivElement>({
61-
opacity: "0",
62-
transform: "scale(0.7)",
63-
});
64-
6558
const { closeModal } = useModal();
6659

67-
useEffect(() => {
68-
const element = ref.current;
69-
if (!element) return;
70-
71-
if (isOpen) {
72-
element.style.opacity = "1";
73-
element.style.transform = "scale(1)";
74-
} else {
75-
element.style.opacity = "0";
76-
element.style.transform = "scale(0.7)";
77-
}
78-
}, [isOpen, ref]);
60+
const { ref } = useOnMountAnimation<HTMLDivElement>({
61+
initialStyles: {
62+
opacity: "0",
63+
transform: "scale(0.7)",
64+
},
65+
animationStyles: {
66+
opacity: "1",
67+
transform: "scale(1)",
68+
},
69+
duration: 200,
70+
delay: 0,
71+
timingFunction: "ease-in-out",
72+
});
7973

8074
return (
8175
<div
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { useCallback, useEffect, useLayoutEffect, useRef } from "react";
2+
3+
export interface UseOnMountAnimationOption {
4+
initialStyles: React.CSSProperties;
5+
animationStyles: React.CSSProperties;
6+
7+
duration: number;
8+
delay: number;
9+
timingFunction: string;
10+
}
11+
12+
export const useOnMountAnimation = <Element extends HTMLElement = HTMLDivElement>({
13+
initialStyles,
14+
animationStyles,
15+
16+
duration = 200,
17+
delay = 0,
18+
timingFunction = "ease-in-out",
19+
}: UseOnMountAnimationOption) => {
20+
const ref = useRef<Element>(null);
21+
const requestAnimationFrameRef = useRef<ReturnType<typeof requestAnimationFrame>>();
22+
23+
const animation = useCallback(() => {
24+
const element = ref.current;
25+
if (!element) throw new Error("[useOnMountAnimation] element 가 존재하지 않습니다.");
26+
27+
element.style.transition = `all ${duration}ms ${timingFunction} ${delay}ms`;
28+
for (const [key, value] of Object.entries(animationStyles)) {
29+
element.style.setProperty(key, value);
30+
}
31+
}, [animationStyles, delay, duration, timingFunction]);
32+
33+
useLayoutEffect(() => {
34+
const element = ref.current;
35+
if (!element) return;
36+
37+
for (const [key, value] of Object.entries(initialStyles)) {
38+
element.style.setProperty(key, value);
39+
}
40+
}, [initialStyles]);
41+
42+
useEffect(() => {
43+
requestAnimationFrameRef.current = requestAnimationFrame(animation);
44+
45+
return () => {
46+
if (requestAnimationFrameRef.current)
47+
cancelAnimationFrame(requestAnimationFrameRef.current);
48+
};
49+
}, [animation]);
50+
51+
return { ref };
52+
};

0 commit comments

Comments
 (0)