Skip to main content

难点:toast 展示到modal背后了

这反而更好讲——「一开始不知道用什么库」 比「我查文档开了个开关」更像真实排查过程。面试里要把故事讲成:从现象 → 试错 → 建立认知 → 再选型/落地


调整后的叙事弧线

现象(Toast 在 Modal 里没了)
↓ 以为是样式/调用时机问题(还不知道有专门方案)
↓ 发现 Modal 和主页面不是同一套层级
↓ 意识到需要「Window 级」展示能力
↓ 调研社区方案 → 找到 notifier + FullWindowOverlay
↓ 读源码验证原理 → 接入并统一封装

面试版讲述(推荐 2~3 分钟)

1. 起点:我只看到现象,不知道答案

我们做钱包 App,Modal 里导入钱包、确认操作后要给用户反馈。一开始就是在页面里调 Toast,普通页面都正常,一打开 Modal 就看不到

当时我的认知还停留在 React 里:是不是 zIndex 不够、position 不对、或者被父容器裁切了。我改了几轮样式,问题还在,说明方向可能错了。

这句话很加分:

那时候我甚至不知道要专门用一个库,也没听说过 FullWindowOverlay,就是把它当成普通 UI 层级问题在查。


2. 转折点:从「样式问题」变成「架构问题」

后来我做了两个对照:

  1. Modal 关闭后再弹 Toast —— 能显示
  2. 同一个 Toast 在非 Modal 页面 —— 能显示

这就把范围缩小了:不是 Toast 组件坏了,是 Modal 场景下的展示层级有问题

接着查 RN Modal 的实现,了解到 Modal 在原生层是单独 presentation 的,跟主 React 树不在同一层,zIndex 解决不了跨 Window 的问题。

到这一步我才明白:我要的不是「把 Toast 样式调对」,而是「把 Toast 挂到 Window 层」——但具体怎么做,我还不清楚。


3. 调研:从「不知道用什么」到「知道要什么能力」

明确需求之后,我去搜类似问题:react native toast above modaloverlay window level iOS

社区里反复出现几个方向:

  • react-native-root-siblings / Portal 类方案
  • react-native-screensFullWindowOverlay
  • 一些 Toast 库内置了对 overlay 的支持

我当时的选型标准很简单:

  1. Modal / Native Stack modal 上能稳定显示
  2. 别每个 Modal 里手写一套
  3. 最好项目里能统一封装(success / error / 队列)

对比下来,选了(或团队选了)react-native-notifier,因为它把 useRNScreensOverlay 和通知队列、动画都封装好了,不需要每个页面自己处理 Window overlay。

这里体现的是选型能力,不是「我会用一个库」。


4. 验证:读源码确认「为什么它能 work」

选定库之后,我没有只调 API,而是顺着源码看了一遍:

showNotificationNotifierRendererFullWindowOverlay

发现 iOS 上如果开了 useRNScreensOverlay,会走 react-native-screens 的原生组件,把内容挂到 Window 级;不开的话就是普通 absolute + zIndex正好解释了我最开始踩的坑

我还做了对照实验:关掉这个开关,Modal 里 Toast 又没了;打开就正常。这样就把「现象 → 原理 → 配置」串起来了。


5. 落地 & 沉淀

最后在 toast.ts 里统一封装,所有 showToast / showErrorToast 都带上 useRNScreensOverlay: true,根布局挂一个 NotifierWrapper,业务侧只调工具函数。

这件事给我的收获是:RN 里 UI「看不见」,不一定是组件写错,要先画清楚 JS 视图树和原生 Window 的关系;选型前先定义「需要什么能力」,再去找库,而不是反过来被库带着走。


30 秒极简版(适合开场)

一开始 Modal 里 Toast 不显示,我以为是 zIndex 问题,改样式没用。对照实验后发现是 Modal 的原生层级导致的,那时我甚至不知道要用专门库。后来调研才知道需要 Window 级 overlay,选了 react-native-notifier,读源码发现它靠 FullWindowOverlay 实现,统一封装后问题解决。


面试官爱听的「真实细节」(可选加一两句)

挑 1~2 个你真实经历过的讲,比背概念更有说服力:

  • 「我先在 Modal 里试了 Alert.alert,能弹出来,更确认是普通 View 层级问题。」
  • 「我一开始想在每个 Modal 里各放一个 Toast,后来发现维护成本太高,才去找全局方案。」
  • 「Android 上行为和 iOS 不一样,我们最后是分平台测过才定规范的。」
  • 「我是看 react-native-screens 文档里 FullWindowOverlay 的说明,才反查到 notifier 里同名封装。」

避免的说法

不太加分更好的说法
「我一开始就用 react-native-notifier」「我一开始连 Window 级 overlay 这个概念都没有」
「我查文档开了个参数」「我先定义问题是什么能力缺失,再去找对应方案」
「这个库就是这样用的」「我读源码验证了它为什么能盖在 Modal 上」

一句收尾(体现成长)

这个问题让我从「调 UI 参数」转到「理解 RN 的渲染边界」;以后遇到弹层、引导、全局 Toast,我会先问:它应该在 JS 树里,还是在 Window 里?


如果你愿意,我可以根据你的真实时间线再改一版,比如:

  1. 完全从零调研(团队里没有 toast 方案)
  2. 从别的库迁移过来(例如之前用 react-native-toast-message 也有同样问题)
  3. 你是排查者,方案是同事引入的(你负责定位根因和验证)

你选哪种,我帮你写成一段可以直接背的「个人经历版」口播稿。