diff --git a/src/hooks/useNotification.tsx b/src/hooks/useNotification.tsx index 6b5946a..52f0e8d 100644 --- a/src/hooks/useNotification.tsx +++ b/src/hooks/useNotification.tsx @@ -3,6 +3,7 @@ import * as React from 'react'; import type { NotificationsProps, NotificationsRef } from '../Notifications'; import Notifications from '../Notifications'; import type { OpenConfig, Placement, StackConfig } from '../interface'; +import { useEvent } from 'rc-util'; const defaultGetContainer = () => document.body; @@ -107,26 +108,29 @@ export default function useNotification( const [taskQueue, setTaskQueue] = React.useState([]); - // ========================= Refs ========================= - const api = React.useMemo(() => { - return { - open: (config) => { - const mergedConfig = mergeConfig(shareConfig, config); - if (mergedConfig.key === null || mergedConfig.key === undefined) { - mergedConfig.key = `rc-notification-${uniqueKey}`; - uniqueKey += 1; - } + const open = useEvent((config) => { + const mergedConfig = mergeConfig(shareConfig, config); + if (mergedConfig.key === null || mergedConfig.key === undefined) { + mergedConfig.key = `rc-notification-${uniqueKey}`; + uniqueKey += 1; + } - setTaskQueue((queue) => [...queue, { type: 'open', config: mergedConfig }]); - }, + setTaskQueue((queue) => [...queue, { type: 'open', config: mergedConfig }]); + }); + + // ========================= Refs ========================= + const api = React.useMemo( + () => ({ + open: open, close: (key) => { setTaskQueue((queue) => [...queue, { type: 'close', key }]); }, destroy: () => { setTaskQueue((queue) => [...queue, { type: 'destroy' }]); }, - }; - }, []); + }), + [], + ); // ======================= Container ====================== // React 18 should all in effect that we will check container in each render diff --git a/tests/index.test.tsx b/tests/index.test.tsx index 4217e31..472b1da 100644 --- a/tests/index.test.tsx +++ b/tests/index.test.tsx @@ -849,4 +849,47 @@ describe('Notification.Basic', () => { expect(document.querySelector('.rc-notification-notice-progress')).toBeFalsy(); }); }); + + describe('Modifying properties through useState can take effect', () => { + it('should show notification and disappear after 5 seconds', async () => { + const Demo: React.FC = () => { + const [duration, setDuration] = React.useState(0); + const [api, holder] = useNotification({ duration }); + + return ( + <> + + + {holder} + + ); + }; + + const { getByTestId } = render(); + + fireEvent.click(getByTestId('show-notification')); + + expect(document.querySelectorAll('.rc-notification-notice').length).toBe(1); + fireEvent.click(getByTestId('change-duration')); + fireEvent.click(getByTestId('show-notification')); + expect(document.querySelectorAll('.rc-notification-notice').length).toBe(2); + + act(() => { + vi.advanceTimersByTime(5000); + }); + + expect(document.querySelectorAll('.rc-notification-notice').length).toBe(1); + }); + }); });