React Hooks 核心原理与实战
王沛
eBay 中国研发中心资深技术专家
10740 人已学习
新⼈⾸单¥59
登录后,你可以任选2讲全文学习
课程目录
已完结/共 25 讲
React Hooks 核心原理与实战
15
15
1.0x
00:00/00:00
登录|注册

14 | 使用浮动层:如何展示对话框,并给对话框传递参数?

你好,我是王沛。今天我们来聊聊如何在 React 中处理对话框。
对话框是前端应用中非常常用的一种界面模式,它们通常是应用中的一个独立窗口,用于展示信息或者输入信息。
但是在 React 中,使用对话框其实并不容易,主要原因在于两点:
一方面,对话框需要先在父组件中声明,才能在子组件中控制其是否显示。
比如说我们需要同时在布局的 header 和 sider 上用菜单去控制某个对话框是否显示,那么这个对话框就必须定义在根组件上。
另一方面,给对话框传递参数只能由 props 传入,这意味着所有的状态管理都需要在更高级别的组件上。而实际上呢,这个对话框的参数可能只在子组件中才会维护,这时我们就需要利用自定义事件将参数回传,非常麻烦。

案例导入:处理对话框的误区

为了方便你理解这两点,我给你举一个实际场景的例子,你就能明白为什么说在 React 中,常用的对话框是比较难处理的。比如说我们需要实现下面这个截图演示的功能:
在这个例子中,我们有一个左右布局的页面。左边栏有一个新建用户的按钮,右边是一个用户列表。点击新建用户的按钮,或者点击表格中的编辑按钮,都会显示同一个对话框。这个对话框根据是否传入用户数据作为参数,来决定是新建还是编辑用户。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了在 React 中处理对话框的挑战和解决方案。作者指出在 React 中使用对话框并不容易,因为对话框需要在父组件中声明才能在子组件中控制其显示,并且给对话框传递参数只能通过 props 传入,导致状态管理需要在更高级别的组件上。作者提出了使用全局状态管理所有对话框的思路,认为对话框在本质上是独立于其他界面的一个窗口,应该独立于各个组件之外,并通过一个全局的机制来管理这些对话框。通过一个实际案例和技术思路,探讨了在 React 中处理对话框的方法及技术特点,为读者提供了有益的技术参考。文章还介绍了如何使用 Redux 和自定义 Hook useNiceModal 来实现全局对话框管理框架,并讨论了如何处理对话框的返回值。整体而言,本文通过实际案例和技术思路,探讨了在 React 中处理对话框的挑战和解决方案,为读者提供了有益的技术参考。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《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-20
    9
  • 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-05
    18
  • 珍惜眼前人
    建议大家一定要跟着老师的代码敲,这节对于我这个新手来说有点难度
    2021-06-29
    10
  • Bug般的存在
    modal.show().then() 感觉这个思路打死我我也想不出来,我不配做程序员😂
    2021-07-04
    1
    3
  • 何用
    弹出层并不仅限于 Modal, 还有 Drawer 等等。这些弹出层显隐处理逻辑都很相似,因而可以考虑个更通用的命名,比如说叫 Overlay。
    2021-06-26
    3
  • 咚门
    其实我感觉有点简单问题复杂化了,文章一开始要解决的问题是两个组件需要用到同一个modal的问题,这时候本身就不该把UserInfoModal放到Sider和UserInfo的父亲组件,这不符合react的组合思想,而是应该在Sider和UserInfo里分别调用UserInfoModal 并控制显示与否就好了。定义全局modal状态管理违背了前面几章讲的文件组合去依赖这个原则吧,整个系统的modal高度耦合,新人来了得花很多时间理解。并且,看代码虽然判断了visible反回null,但是本身是有多少个modal就一直存在了少个 instance,而modal往往只能同时存在一个。
    2021-10-05
    2
  • 林十二XII
    并非简单问题复杂化, 值得二刷的章节
    2023-04-09归属地:北京
    1
  • 灵感_idea
    本章节的讲解,看似是把简单问题复杂化,也不太好理解,但其实老师只是提供一种思路,即,在考虑代码复用性、维护性时,不要头疼医头,脚疼医脚,可以有一种更系统化,通用化的方式解决问题,初始成本是高的,后续就低很多、清晰很多了。从另一个角度看,这些代码或许不适合在初建项目时使用,而是在迭代、重构的时候更佳,即不过早优化,就好理解了。
    2022-12-26归属地:广东
    1
  • Geek_4e92cc
    为什么不用传送门传到根节点render呢?
    2022-05-30
    1
收起评论
显示
设置
留言
25
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部