14 | 使用浮动层:如何展示对话框,并给对话框传递参数?
王沛
你好,我是王沛。今天我们来聊聊如何在 React 中处理对话框。
对话框是前端应用中非常常用的一种界面模式,它们通常是应用中的一个独立窗口,用于展示信息或者输入信息。
但是在 React 中,使用对话框其实并不容易,主要原因在于两点:
一方面,对话框需要先在父组件中声明,才能在子组件中控制其是否显示。
比如说我们需要同时在布局的 header 和 sider 上用菜单去控制某个对话框是否显示,那么这个对话框就必须定义在根组件上。
另一方面,给对话框传递参数只能由 props 传入,这意味着所有的状态管理都需要在更高级别的组件上。而实际上呢,这个对话框的参数可能只在子组件中才会维护,这时我们就需要利用自定义事件将参数回传,非常麻烦。
案例导入:处理对话框的误区
为了方便你理解这两点,我给你举一个实际场景的例子,你就能明白为什么说在 React 中,常用的对话框是比较难处理的。比如说我们需要实现下面这个截图演示的功能:
在这个例子中,我们有一个左右布局的页面。左边栏有一个新建用户的按钮,右边是一个用户列表。点击新建用户的按钮,或者点击表格中的编辑按钮,都会显示同一个对话框。这个对话框根据是否传入用户数据作为参数,来决定是新建还是编辑用户。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了在 React 中处理对话框的挑战和解决方案。作者指出在 React 中使用对话框并不容易,因为对话框需要在父组件中声明才能在子组件中控制其显示,并且给对话框传递参数只能通过 props 传入,导致状态管理需要在更高级别的组件上。作者提出了使用全局状态管理所有对话框的思路,认为对话框在本质上是独立于其他界面的一个窗口,应该独立于各个组件之外,并通过一个全局的机制来管理这些对话框。通过一个实际案例和技术思路,探讨了在 React 中处理对话框的方法及技术特点,为读者提供了有益的技术参考。文章还介绍了如何使用 Redux 和自定义 Hook useNiceModal 来实现全局对话框管理框架,并讨论了如何处理对话框的返回值。整体而言,本文通过实际案例和技术思路,探讨了在 React 中处理对话框的挑战和解决方案,为读者提供了有益的技术参考。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《React Hooks 核心原理与实战》,新⼈⾸单¥59
《React Hooks 核心原理与实战》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(25)
- 最新
- 精选
- Brave对于思考题这是我的想法: import React, {useContext, useReducer} from 'react' import {reducer, ModalContext} from "./NiceModal/modalContext"; import Demo1 from "./demo1"; const Main = () => { const context = useContext(ModalContext) const [state, dispatch] = useReducer(reducer, context.state) return ( <ModalContext.Provider value={{ state, dispatch, }}> <Demo1/> </ModalContext.Provider> ) } export default Main 创建useNiceModal: const useNiceModal = (modalId) => { const {state, dispatch} = useContext(ModalContext) const args = state[modalId] const show = useCallback((args) => { dispatch({ type: 'show', modalId, args }) }, [modalId, args, dispatch]) const hide = useCallback(() => { dispatch({ type: 'hide', modalId }) }, [dispatch, modalId]) return { show, hide, args, visible: !!args, } } export default useNiceModal 在Demo1中: const Demo1 = () => { const modalId = 'my-first-modal' const Content = (props) => { return ( <div>Hello world!</div> ) } const MyModal = createNiceModal({ modalId, title: '这是我的标题', content: '这是我的内容' }, Content) const modal = useNiceModal(modalId) return ( <div> <button onClick={() => modal.show()}> 打开弹窗 </button> <MyModal/> </div> ) } export default Demo1
作者回复: 回答的很好,结合了 useReducer 和 useContext ,可以看到,从 redux 转到 context,基本代码逻辑是没有变化的,都是 dispatch action。这里也看到了 useReducer 的使用场景,通常都会和 useContext 结合来完成一些比较复杂的数据管理逻辑,在一定程度可以取代 redux。
2021-08-209 - SenjougaharaSama为啥不直接通过portal?
作者回复: 文中示例的 antd modal 就是基于 portal 实现的。
2021-07-16 - 咚门其实我感觉有点简单问题复杂化了,文章一开始要解决的问题是两个组件需要用到同一个modal的问题,这时候本身就不该把UserInfoModal放到Sider和UserInfo的父亲组件,这不符合react的组合思想,而是应该在Sider和UserInfo里分别调用UserInfoModal 并控制显示与否就好了。定义全局modal状态管理违背了前面几章讲的文件组合去依赖这个原则吧,整个系统的modal高度耦合,新人来了得花很多时间理解。并且,看代码虽然判断了visible反回null,但是本身是有多少个modal就一直存在了少个 instance,而modal往往只能同时存在一个。2021-10-0518
- 珍惜眼前人建议大家一定要跟着老师的代码敲,这节对于我这个新手来说有点难度2021-06-2910
- Bug般的存在modal.show().then() 感觉这个思路打死我我也想不出来,我不配做程序员😂2021-07-0413
- 何用弹出层并不仅限于 Modal, 还有 Drawer 等等。这些弹出层显隐处理逻辑都很相似,因而可以考虑个更通用的命名,比如说叫 Overlay。2021-06-263
- 咚门其实我感觉有点简单问题复杂化了,文章一开始要解决的问题是两个组件需要用到同一个modal的问题,这时候本身就不该把UserInfoModal放到Sider和UserInfo的父亲组件,这不符合react的组合思想,而是应该在Sider和UserInfo里分别调用UserInfoModal 并控制显示与否就好了。定义全局modal状态管理违背了前面几章讲的文件组合去依赖这个原则吧,整个系统的modal高度耦合,新人来了得花很多时间理解。并且,看代码虽然判断了visible反回null,但是本身是有多少个modal就一直存在了少个 instance,而modal往往只能同时存在一个。2021-10-052
- 林十二XII并非简单问题复杂化, 值得二刷的章节2023-04-09归属地:北京1
- 灵感_idea本章节的讲解,看似是把简单问题复杂化,也不太好理解,但其实老师只是提供一种思路,即,在考虑代码复用性、维护性时,不要头疼医头,脚疼医脚,可以有一种更系统化,通用化的方式解决问题,初始成本是高的,后续就低很多、清晰很多了。从另一个角度看,这些代码或许不适合在初建项目时使用,而是在迭代、重构的时候更佳,即不过早优化,就好理解了。2022-12-26归属地:广东1
- Geek_4e92cc为什么不用传送门传到根节点render呢?2022-05-301
收起评论