题目又名:简略弹窗、多弹窗、简单弹窗怎么做代码和状态的解耦。

关键字:react / modal

问题

理论业务中,不乏弹窗组件中蕴含大量简单的业务逻辑。如:

function Order() {    // 省略上百行办法状态    const [visible,setVisible] = useState(false)    const withModalState = useState<any>()        return (        <Modal>            <Input/>            <Input/>            <Select/>            <Checkbox/>        </Modal>    ) }

甚至还有多弹窗的情景。如:

function Order() {    // 省略上百行办法状态    const [visible1,setVisible1] = useState(false)    const [visible2,setVisible2] = useState(false)    const [visible3,setVisible3] = useState(false)        const withModalState1 = useState<any>()    const withModalState2 = useState<any>()    const withModalState3 = useState<any>()        // 省略 不懂多少 handlexx    return (        <main>            ...            <Modal1></* 省略很多代码 */></Modal1>            <Modal2></* 省略很多代码 */></Modal3>            <Modal3></* 省略很多代码 */></Modal3>        </main>    ) }

十分的痛:

  1. 如果弹窗在解决完外部流程后,又还有返回值,这有又会有一大通的处理函数。
  2. 如果这些代码都写在一个文件中还是不太容易保护的。

而且随着业务的断增长,每次这么体验很差。

冀望的应用形式

因而有没有一种更贴近业务理论的计划。

让弹窗只专一于本人的外部事务,同时又能将控制权交给调用方呢。

或者说我就是不喜爱 Modal 代码堆在一起……

如下:

// Modal1.tsxexport function Modal1(props) return <Modal></* ... */></Modal>// 甚至能够将MOdal中的逻辑做的更聚合。通过2次封再导出给各方应用export const function Check_XXX_Window() {/* */ return open(Modal1)}export const function Check_XXX_By_Id_Window() { return open(Modal1)}export const function Check_XXX_Of_Ohter_Window() { return open(Modal1)}// Order.tsxfunction Order() {    function xxHndanle {         const expect = Check_XXX_Window(Modal1,args) // 调用办法,传入参数,取得预期值 ,实现1个流程    }    return (        <main>            ...            // 不理论挂载 Modal 组件        </main>    ) }

像这样拆散两者的代码,这样解决起来必定是清新很多的。

实现思路

实现的思路都是统一的。

  1. 创立占位符组件,放到利用的某处。
  2. 将相干状态集治理,并与Modal做好关联。
  3. 裸露控制权。

因而基于不同的状态治理计划,实现是多种多样的。置信很多大佬都本人外部封装过不少了。

然而在此基础上,我还想要3点。

  1. API应用简略,但也容许肯定配置。
  2. 返回值类型推导,除了帮我治理 close 和 open 还要让我用起来带提醒的。
  3. 无入侵性,不依赖框架以外的货色。

ez-modal-react

emm......苦于市面上找不到这类产品(感觉同类并不多……探讨的也不多?)

于是我本人开源了一个。回应上文实现思路,能够点击看代码,几百行而已。

并不是突发奇想而来,其实相干个性早就在企业外部是应用多年了。我也是受前辈和社区启发。

根本个性

  1. 基于Promise封装
  2. 返回值类型推导
  3. 没有入侵性,体积小。

应用画面

import EasyModal, { InnerModalProps } from 'ez-modal-react';+ interface IProps extends InnerModalProps<'fybe?'> /*传入返回值类型*/ {+   age: number;+   name: string;+ }export const InfoModal = EasyModal.create(+ (props: Props) => {  return (    <Modal      title="Hello"      open={props.visible}      onOk={() => {+       props.hide(); // warn 应有 1 个参数,但取得 0 个。 (property) hide: (result: "fybe?") => void ts(2554)      }}      onCancel={() => {       props.hide(null); //safe hide 承受 null 作为参数。它兼具 hide resolve 两种性能。      }}    >      <h1>{props.age}</h1>    </Modal>  );});+ // warn 类型 "{ name: string; }" 中短少属性 "age",但类型 "ModalProps<Props, "fybe?">" 中须要该属性。EasyModal.show(InfoModal, { name: 'foo' }).then((resolve) => {  console.log(resolve);+ //输入 "fybe?" });

也反对用 hook

import EasyModal, { useModal, InnerModalProps } from 'ez-modal-react';interface IProps extends InnerModalProps<'苏振华'>/* 指定返回值类型 */ {  age: number;  name: string;}export const Info = EasyModal.create((props: Props) => {  const modal = useModal<Props>();   function handleOk(){      modal.hide(); // ts(2554) (property) hide: (result: "苏振华") => void ts(2554)  }   return  <Modal open={modal.visible} onOk={handleOk} onCancel={modal.hide}></Modal>});EasyModal.show(Info,{age:18,}) // 短少属性 "age"

还有一些个性如反对配置 hide 弹窗时的默认行为。(我认为大多数状况下可能用不上)

export const Info = EasyModal.create((props: Props) => {  const modal = useModal<Props>();   function handleOk(){      modal.hide(); +     modal.resolve('苏振华') // 须要手动抛出胜利+     modal.remove() // 须要手动登记组件。可用于重复关上弹窗,然而不心愿状态被革除的场景。  }   return  <Modal open={modal.visible} onOk={handleOk} onCancel={modal.hide}></Modal>// Ohter.tsxEasyModal.open(Info, {},+  config:{+    resolveOnHide:false, // 默认为 true+    removeOnHide:false,  // 默认为 true+  });

当然以上是针对弹窗内有简单业务场景的情况。

大部分场景都是调用方只在乎 open或close ,仅仅解耦代码这一项益处,就能够让代码变得清新。

如罕用的有展现类,设置类的弹窗,TS类型都用不上。

仓库

其余就不一一介绍了,次要的曾经说完了,想理解更多,能够看看仓库。github

Codesandbox Demo

Codesandbox是一个线上集成环境,能够间接关上玩玩。点击 Demo Link 返回

初衷

让弹窗应用更轻松。

包名 ez 结尾,是因为我DOTA在东南亚打多了,感觉该词特地贴切。

授之于鱼叉

GitHub仓库地址
:ez-modal-react

感觉有用帮我点个星\~\~\~ 感恩,有啥问题能够提出,看到会回复。如果有须要会继续保护该我的项目。