Skip to content

Conversation

@YyumeiZhang
Copy link
Collaborator

@YyumeiZhang YyumeiZhang commented Nov 25, 2025

中文模板 / Chinese Template

What kind of change does this PR introduce? (check at least one)

  • Bugfix
  • Feature
  • Code style update
  • Refactor
  • Test Case
  • TypeScript definition update
  • Document improve
  • CI/CD improve
  • Branch sync
  • Other, please describe:

PR description

Fixes #2743

复现版本:2.88.3
复现代码

import './App.css';
import { Button, Toast, Notification } from "@douyinfe/semi-ui-19";

function App() {
      return (
            <>
                <Button onClick={async () => {
                    // 此处的请求对复现问题很重要
                    const res = await fetch('https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/abstract.jpg')
                    console.log(res)
                    Toast.success({content: "Hello World"})
                }}>
                    Display Toast
                </Button>
                <br /><br />
                <Button
                    onClick={async () =>{
                        // 此处的请求对复现问题很重要
                        const res = await fetch('https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/abstract.jpg')
                        console.log(res)
                         Notification.open({
                            title: 'Hi, Bytedance',
                            content: 'ies dance dance dance',
                            duration: 3,
                        })
                    }}
                >
                    Display Notification
                </Button>
            </>
      )
}

export default App

虽然 react v19 中,root.render 是同步调用,但是并不意味中被渲染的元素的 ref 方法调用也是同步的, Toast 和 Notification 中都有下面的逻辑

let saveRef;
const root = createRoot(div);
// root.render 是同步方法,但是 ClassA 的 ref 方法并不一定立刻被调用
root.render(ReactCreateElement(ClassA, { ref: instance => saveRef = instance  }
// 此时 saveRef 并不一定被赋值,因此调用方法会出现 TypeError
saveRef.methodA()

因此 TypeError。

修复思路
在 saveRef 还没赋值时,先缓存需要调用的方法的 props,待 ref 方法调用,再使用 props 去调用方法

Changelog

🇨🇳 Chinese

  • Fix: 修复 React v19 下 Toast/Notification 首次调用可能出现 TypeError 的问题

🇺🇸 English

  • Fix: Fixed an issue in React v19 where a TypeError might occur on the first call to Toast/Notification.

Checklist

  • Test or no need
  • Document or no need
  • Changelog or no need

Other

  • Skip Changelog

Additional information

…he first Toast/Notification imperative call in React v19
@codesandbox-ci
Copy link

codesandbox-ci bot commented Nov 25, 2025

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 94700d4:

Sandbox Source
pr-story Configuration

@cypress
Copy link

cypress bot commented Nov 25, 2025

semi-design    Run #3384

Run Properties:  status check passed Passed #3384  •  git commit 0cd0b7a0a4 ℹ️: Merge 94700d4414b347d110729803dcd97e5dc08168d2 into 4db0d84458aca1124cd7f7e76893...
Project semi-design
Branch Review fix/19-toast
Run status status check passed Passed #3384
Run duration 08m 20s
Commit git commit 0cd0b7a0a4 ℹ️: Merge 94700d4414b347d110729803dcd97e5dc08168d2 into 4db0d84458aca1124cd7f7e76893...
Committer YyumeiZhang
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 13
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 291
⚠️ You've recorded test results over your free plan limit.
Upgrade your plan to view test results.
View all changes introduced in this branch ↗︎

@YannLynn YannLynn changed the title fix: [Toast][Notification] Fixed a TypeError issue that occurred on t… fix: [Toast][Notification] Fixed a TypeError issue that occurred on the first Toast/Notification imperative call in React v19 Nov 28, 2025
};

/* REACT_19_START */
// const toastQueue: Array<{ opts: ToastReactProps, id: string }> = [];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Toast 支持通过 ToastFactory.create 来在应用中设置不同 config 的 Toast,目前 toastQueue 定义在全局,生成的所有的 ToastList 类都会共享同一个 queue 数组,会出现抢占同一个 queue 的情况发生,把 queue 添加在 ToastList 的静态属性是更合适些,这样不同的 Toast 实例只会消费自己的 queue ,互不干扰。

…he first Toast/Notification imperative call in React v19
@YannLynn YannLynn merged commit 6d38db9 into main Dec 5, 2025
13 checks passed
@YannLynn YannLynn deleted the fix/19-toast branch December 5, 2025 03:00
@cypress
Copy link

cypress bot commented Dec 5, 2025

semi-design    Run #3391

Run Properties:  status check passed Passed #3391  •  git commit 6d38db9c64: fix: [Toast][Notification] Fixed a TypeError issue that occurred on the first To...
Project semi-design
Branch Review main
Run status status check passed Passed #3391
Run duration 08m 16s
Commit git commit 6d38db9c64: fix: [Toast][Notification] Fixed a TypeError issue that occurred on the first To...
Committer YyumeiZhang
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 13
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 291
⚠️ You've recorded test results over your free plan limit.
Upgrade your plan to view test results.
View all changes introduced in this branch ↗︎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

React 19 适配

3 participants