Skip to content

Commit 64fcb17

Browse files
committed
fix : closeModal method logic
1 parent 6751a36 commit 64fcb17

File tree

6 files changed

+129
-34
lines changed

6 files changed

+129
-34
lines changed

src/components/modals/BottomSheet.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ const BottomSheet = ({
2828

2929
useEffect(() => {
3030
onAfterOpen();
31-
return () => onAfterClose();
32-
}, [onAfterOpen, onAfterClose]);
31+
return () => {
32+
onAfterClose();
33+
};
34+
}, []);
3335

3436
return (
3537
<Wrapper>

src/components/modals/Modal.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ const Modal = ({
2626

2727
useEffect(() => {
2828
onAfterOpen();
29-
return () => onAfterClose();
30-
}, [onAfterOpen, onAfterClose]);
29+
return () => {
30+
onAfterClose();
31+
};
32+
}, []);
3133

3234
return (
3335
<Wrapper className={isOpen ? 'fade-in' : 'fade-out'}>

src/components/provider/ModalProvider.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { css, Global } from '@emotion/react';
2-
import React, { createContext, ReactNode, useMemo, useState } from 'react';
2+
import React, {
3+
createContext,
4+
ReactNode,
5+
SetStateAction,
6+
useMemo,
7+
useState,
8+
} from 'react';
39

410
import BottomSheet from '@/components/modals/BottomSheet';
511
import Modal from '@/components/modals/Modal';
@@ -13,7 +19,7 @@ type Props = {
1319
export const ModalContext = createContext({
1420
deleteDelay: 0,
1521
modals: new Map(),
16-
setModals: (state: Modals) => {},
22+
setModals: (value: SetStateAction<Modals>) => {},
1723
});
1824

1925
const ModalProvider = ({ deleteDelay = 200, children }: Props) => {

src/hooks/useModal.tsx

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,19 @@ const useModal = () => {
2626

2727
const openModal = useCallback(
2828
(props: ModalProps) => {
29-
const newMap = new Map(_modals);
30-
if (props.id && newMap.has(props.id)) return;
31-
const id = props.id || createUid();
32-
props.id = id;
33-
props.type = props.type || ModalType.Modal;
34-
props.isOpen = true;
35-
props.createdAt = new Date().getTime();
36-
newMap.set(id, props);
37-
setModals(newMap);
29+
setModals((prevMap: Modals) => {
30+
const newMap = new Map(prevMap);
31+
if (props.id && newMap.has(props.id)) {
32+
return prevMap;
33+
}
34+
const id = props.id || createUid();
35+
props.id = id;
36+
props.type = props.type || ModalType.Modal;
37+
props.isOpen = true;
38+
props.createdAt = new Date().getTime();
39+
newMap.set(id, props);
40+
return newMap;
41+
});
3842
},
3943
[setModals]
4044
);
@@ -43,26 +47,33 @@ const useModal = () => {
4347
async (id?: string) => {
4448
const _id = id || getRecentModalId();
4549
if (!_id) return;
46-
const newMap = new Map(_modals);
47-
const props = newMap.get(_id);
48-
if (!props) return;
49-
props.isOpen = false;
50-
newMap.set(_id, props);
51-
setModals(newMap);
50+
setModals((prevMap: Modals) => {
51+
const newMap = new Map(prevMap);
52+
const props = newMap.get(_id);
53+
if (!props) {
54+
return prevMap;
55+
}
56+
props.isOpen = false;
57+
newMap.set(_id, props);
58+
return newMap;
59+
});
5260
await delay(deleteDelay);
53-
newMap.delete(_id);
54-
return setModals(new Map(newMap));
61+
setModals((prevMap: Modals) => {
62+
const newMap = new Map(prevMap);
63+
newMap.delete(_id);
64+
return newMap;
65+
});
5566
},
5667
[deleteDelay, setModals, getRecentModalId]
5768
);
5869

5970
const changeModal = useCallback(
6071
async (props: ModalProps) => {
6172
await closeModal();
62-
await delay(20);
73+
await delay(deleteDelay / 2);
6374
openModal(props);
6475
},
65-
[openModal, closeModal]
76+
[deleteDelay, openModal, closeModal]
6677
);
6778

6879
const openBottomSheet = (props: ModalProps) => {

src/stories/Modal.stories.tsx

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import styled from '@emotion/styled';
12
import type { Meta } from '@storybook/react';
2-
import React from 'react';
3+
import React, { useState } from 'react';
34

45
import useModal from '@/hooks/useModal';
56

@@ -12,17 +13,89 @@ const meta = {
1213
export default meta;
1314

1415
const App = () => {
15-
const { openModal } = useModal();
16+
const { openModal, closeModal } = useModal();
17+
18+
const [count, setCount] = useState(0);
19+
20+
const openTest1Modal = () => {
21+
openModal({
22+
id: 'test1',
23+
component: () => (
24+
<div>
25+
<Button onClick={openTest2Modal}>openTest2Modal</Button>
26+
</div>
27+
),
28+
});
29+
};
30+
31+
const openTest2Modal = () => {
32+
openModal({
33+
id: 'test2',
34+
component: () => <div>test2</div>,
35+
onAfterClose: async () => {
36+
closeModal('test1');
37+
},
38+
});
39+
};
40+
41+
const open2Modal = () => {
42+
openModal({
43+
id: 'test1',
44+
component: () => (
45+
<div>
46+
<p>test1</p>
47+
<p>test1</p>
48+
<p>test1</p>
49+
<p>test1</p>
50+
</div>
51+
),
52+
});
53+
openModal({
54+
id: 'test2',
55+
component: () => (
56+
<div>
57+
<Button onClick={close2Modal}>close2Modal</Button>
58+
</div>
59+
),
60+
});
61+
};
62+
63+
const close2Modal = () => {
64+
closeModal('test1');
65+
closeModal('test2');
66+
};
67+
68+
const batchTest = () => {
69+
// setCount(count + 1);
70+
// setCount(count + 1);
71+
// setCount(count + 1);
72+
setCount((c) => c + 1);
73+
setCount((c) => c + 1);
74+
setCount((c) => c + 1);
75+
};
1676

1777
return (
18-
<div>
19-
<button onClick={() => openModal({ component: () => <div>123</div> })}>
20-
Open Modal
21-
</button>
22-
</div>
78+
<Container>
79+
{/* <Button onClick={batchTest}>{`count : ${count}`}</Button> */}
80+
<Button onClick={openTest1Modal}>openTest1Modal</Button>
81+
<Button onClick={open2Modal}>open2Modal</Button>
82+
</Container>
2383
);
2484
};
2585

2686
export const Modal_ = {
2787
render: () => <App></App>,
2888
};
89+
90+
const Container = styled.div`
91+
display: flex;
92+
flex: wrap;
93+
gap: 16px;
94+
`;
95+
const Button = styled.button`
96+
border: 1px solid black;
97+
padding: 8px;
98+
border-radius: 8px;
99+
background-color: transparent;
100+
cursor: pointer;
101+
`;

src/types/modal.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ export interface ModalProps {
2828
// bottomSheet style
2929
height?: number | string;
3030

31+
// content
32+
component?: () => JSX.Element;
33+
3134
// function
3235
onAfterOpen?: () => void;
3336
onAfterClose?: () => void;
34-
35-
component?: () => JSX.Element;
3637
}
3738
export type Modals = Map<string, ModalProps>;

0 commit comments

Comments
 (0)