From f722b4c17d6f14822341ff53754c32c0ba850b0e Mon Sep 17 00:00:00 2001 From: Heising Date: Fri, 10 Nov 2023 18:08:01 +0800 Subject: [PATCH] fix(notification): fix notification, replace flushSync --- src/notification/NotificationList.tsx | 25 ++++++++++++++++++------- src/notification/NotificationPlugin.ts | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/notification/NotificationList.tsx b/src/notification/NotificationList.tsx index fffe5b20e4..e1389579a9 100644 --- a/src/notification/NotificationList.tsx +++ b/src/notification/NotificationList.tsx @@ -1,5 +1,4 @@ import React, { forwardRef, useImperativeHandle, useState, useEffect } from 'react'; -import { flushSync } from 'react-dom'; import { render } from '../_util/react-render'; import useConfig from '../hooks/useConfig'; import { @@ -86,9 +85,11 @@ const NotificationList = forwardRef { - requestAnimationFrame(() => { + // setTimeout replace requestAnimationFrame + // 在useEffect启动关闭Notification时,requestAnimationFrame可能会过早执行,导致ref.current为undefined + setTimeout(() => { resolve(ref.current); - }); + }, 1000 / 60); }); }; @@ -127,6 +128,9 @@ const NotificationList = forwardRef => new Promise((resolve) => { // Fix the bug of Notification triggered for the first time in React 18 concurrent mode - flushSync(() => { + function idle() { if (listMap.has(placement)) { resolve(listMap.get(placement)); - } else { + return; + } + if (!renderNotification) { + renderNotification = true; render( { + renderNotification = false; listMap.set(placement, instance); resolve(instance); }} />, attach, ); - } - }); + return; + } // 循环执行,直到NotificationList的回调执行 + setTimeout(idle, 1000 / 60); + } + idle(); }); diff --git a/src/notification/NotificationPlugin.ts b/src/notification/NotificationPlugin.ts index d9ab8f757e..cee2d7ca4c 100644 --- a/src/notification/NotificationPlugin.ts +++ b/src/notification/NotificationPlugin.ts @@ -67,5 +67,5 @@ NotificationPlugin.success = (options) => renderNotification('success', options) NotificationPlugin.warning = (options) => renderNotification('warning', options); NotificationPlugin.error = (options) => renderNotification('error', options); NotificationPlugin.close = (promise) => promise.then((instance) => instance.close()); -NotificationPlugin.closeAll = () => listMap.forEach((list) => list.removeAll()); +NotificationPlugin.closeAll = () => [...listMap.values()].forEach((list) => list.removeAll()); NotificationPlugin.config = (options) => setGlobalConfig(options);