Skip to content

Commit 11bc7f6

Browse files
authored
fix: hooks should support update (#161)
* fix: hooks should support update * test: Fix lint * remove tsconfig in gitignore
1 parent 2c5e1fa commit 11bc7f6

File tree

4 files changed

+97
-8
lines changed

4 files changed

+97
-8
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,3 @@ es
3030
coverage
3131
yarn.lock
3232
package-lock.json
33-
tsconfig.json

src/useNotification.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as React from 'react';
2-
import Notification, { NoticeFunc, NoticeContent } from './Notification';
2+
import type { NoticeFunc, NoticeContent } from './Notification';
3+
import type Notification from './Notification';
34
import Notice from './Notice';
45

56
export default function useNotification(
@@ -9,14 +10,28 @@ export default function useNotification(
910
const [elements, setElements] = React.useState<React.ReactElement[]>([]);
1011

1112
function notify(noticeProps: NoticeContent) {
13+
let firstMount = true;
1214
notificationInstance.add(noticeProps, (div, props) => {
1315
const { key } = props;
1416

15-
if (div && !createdRef.current[key]) {
17+
if (div && (!createdRef.current[key] || firstMount)) {
1618
const noticeEle = <Notice {...props} holder={div} />;
1719
createdRef.current[key] = noticeEle;
18-
setElements(originElements => [...originElements, noticeEle]);
20+
21+
setElements((originElements) => {
22+
const index = originElements.findIndex((ele) => ele.key === props.key);
23+
24+
if (index === -1) {
25+
return [...originElements, noticeEle];
26+
}
27+
28+
const cloneList = [...originElements];
29+
cloneList[index] = noticeEle;
30+
return cloneList;
31+
});
1932
}
33+
34+
firstMount = false;
2035
});
2136
}
2237

tests/hooks.test.tsx

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import React from 'react';
2-
import { mount, ReactWrapper } from 'enzyme';
2+
import type { ReactWrapper } from 'enzyme';
3+
import { mount } from 'enzyme';
34
import Notification from '../src';
4-
import { NotificationInstance } from '../src/Notification';
5+
import type { NotificationInstance } from '../src/Notification';
56

67
require('../assets/index.less');
78

89
async function timeout(delay = 0) {
9-
return new Promise(resolve => {
10+
return new Promise((resolve) => {
1011
setTimeout(resolve, delay);
1112
});
1213
}
@@ -24,7 +25,7 @@ describe('Notification.Hooks', () => {
2425
wrapper = mount(<div>{node}</div>);
2526
},
2627
} as any,
27-
notification => {
28+
(notification) => {
2829
instance = notification;
2930
},
3031
);
@@ -64,4 +65,62 @@ describe('Notification.Hooks', () => {
6465

6566
instance.destroy();
6667
});
68+
69+
it('key replace', async () => {
70+
let instance: NotificationInstance;
71+
72+
let wrapper: ReactWrapper;
73+
Notification.newInstance(
74+
{
75+
TEST_RENDER: (node: React.ReactElement) => {
76+
wrapper = mount(<div>{node}</div>);
77+
},
78+
} as any,
79+
(notification) => {
80+
instance = notification;
81+
},
82+
);
83+
84+
await timeout(0);
85+
86+
const Demo = () => {
87+
const [notify, holder] = instance.useNotification();
88+
return (
89+
<>
90+
<button
91+
type="button"
92+
onClick={() => {
93+
notify({
94+
key: 'little',
95+
duration: 1000,
96+
content: <div className="context-content">light</div>,
97+
});
98+
99+
setTimeout(() => {
100+
notify({
101+
key: 'little',
102+
duration: 1000,
103+
content: <div className="context-content">bamboo</div>,
104+
});
105+
}, 500);
106+
}}
107+
/>
108+
{holder}
109+
</>
110+
);
111+
};
112+
113+
const demo = mount(<Demo />);
114+
demo.find('button').simulate('click');
115+
116+
await timeout(10);
117+
expect(demo.find('.context-content').text()).toEqual('light');
118+
119+
await timeout(600);
120+
expect(demo.find('.context-content').text()).toEqual('bamboo');
121+
122+
instance.destroy();
123+
124+
wrapper.unmount();
125+
});
67126
});

tsconfig.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"compilerOptions": {
3+
"target": "esnext",
4+
"moduleResolution": "node",
5+
"baseUrl": "./",
6+
"jsx": "preserve",
7+
"declaration": true,
8+
"skipLibCheck": true,
9+
"esModuleInterop": true,
10+
"paths": {
11+
"@/*": ["src/*"],
12+
"@@/*": ["src/.umi/*"],
13+
"rc-notification": ["src/index.ts"]
14+
}
15+
}
16+
}

0 commit comments

Comments
 (0)