孤狼的博客
React项目中优雅的管理多弹窗 - 2022-06-24

项目中,我们经常碰到多弹框的需求,以一个活动为例:

  • 在活动未开始时,我们需要需要提示用户活动未开始,可以先预约,此时我们有一个组件 Modal1;
  • 用户预约成功后,给一个预约成功的弹框 Modal2;
  • 活动开始时,用户参与一些互动,获取积分之类的 Modal3;
  • 领取成功、领取失败、以及失败的各种理由:Modal4、Modal5...Modaln

虽然有一些Modal我们可以进行合并,在一个modal中通过状态控制内容展示,但实际情况中modal还是会有很多,这时候我们要管理各种modal的显示与关闭逻辑,就比较繁琐。

比如有3个modal,通常我们用3个bool状态去保存它是否可见:

jsx

当然我们可以把Modal封装为hook来用,状态在hook内部管理,对外暴露ui、展示、关闭的方法:

jsx

看起来是要稍微简洁一点,但如果我们弹框再多一点呢?10个?当然我们可以给每个modal分配一个key,然后用一个状态指向打开的modal key,这样就可以用一个状态一个打开方法,一个关闭方法来管理了:

jsx

如果说需要支持同时展示多个弹框,那么我们只需要把modalKey定义为数组即可,现在看比之前的代码是要少了一些,但还不够,如果我们的弹框需要跨组件共享呢?那我们得把Modal挂在页面最外层,然后用状态管理来保存组件状态?这样的代码确实是不太优雅了。

其实我们需要解决的根本问题是什么呢?

  • 需要去控制弹框打开、关闭;
  • 还需要能全局控制;

在没有React的时候,原生js中我们会怎么做呢?

js

再回到React,只不过我们要展示的内容是 ReactNode 而已,把ReactNode渲染到dom节点上就可以了,没错,就是那个每个页面中我们都在用,又最没存在感的方法:

jsx

既然 render 可以把 App挂载到 dom中,那它也可以把我们的 Modal 挂上去啊!至于关闭,直接移除ReactNode就行了,简单粗暴,这里就直接上代码了:

jsx

用起来也是非常简单,直接导入modal,调用对应的方法就行:

jsx

现在modal完全和页面组件解耦了,代码看起来舒服多了,用起来也更优雅了。

如果你也曾被多弹框困扰,那就赶紧去试试吧!