使用React Hook Dialog管理对话框弹窗组件

931 阅读2分钟

介绍

最近做了一个开源库:React Hook Dialog (求Star 🌟🌟🌟)

GitHub: github.com/jsun969/rea…

这个库能够解决React中对话框组件的复用问题,用类型安全的方式复用对话框组件,很有效地提高开发效率

安装

npm install react-hook-dialog

使用

使用非常方便,并且只要声明一次对话框组件,就可以在各种地方复用

以下这个例子用Ant Design作为UI库,完整的例子在:
codesandbox.io/s/rhd-antd-…

首先创建一个文件,用来定义这个对话框的默认属性

lib/dialog.ts

import { createDialogs, createDialogHooks } from "react-hook-dialog";

type CustomDialogProps = {
  title: string;
  content: string;
  onOk: () => void;
  onCancel: () => void;
};

// 初始化对话框组件
// 如果有多个对话框组件,为了类型安全,可以传入两个泛型
// 1.对话框组件属性的联合类型(props)
// 2.对话框组件名的联合类型(name)
export const dialogs = createDialogs<CustomDialogProps, "customDialog">({
  customDialog: {
    title: "",
    content: "",
    onOk: () => {
      console.log("ok");
    },
    onCancel: () => {
      console.log("cancel");
    }
  }
});

// 创建类型安全的Hook
export const dialog = createDialogHooks(dialogs);

接下来,在对话框组件中,useDialogController 接管组件所有属性

import { dialog } from "../lib/dialog";
import { Modal } from "antd";

const CustomDialog: React.FC = () => {
  const { isOpen, handleClose, props } = dialog.useDialogController(
    "customDialog"
  );

  return (
    <Modal
      visible={isOpen}
      onOk={() => {
        props.onOk();
        handleClose();
      }}
      onCancel={() => {
        props.onCancel();
        handleClose();
      }}
    >
      <h3>{props.title}</h3>
      <p>{props.content}</p>
    </Modal>
  );
};

export default CustomDialog;

在入口文件中,使用DialogProvider将对话框应用全局

import App from "./App";
import React from "react";
import ReactDOM from "react-dom/client";
import "antd/dist/antd.css";

import CustomDialog from "./components/CustomDialog";
import { dialogs } from "./lib/dialog";
import { DialogProvider } from "react-hook-dialog";

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
  <React.StrictMode>
    <DialogProvider dialogs={dialogs}>
      <App />
      <CustomDialog />
    </DialogProvider>
  </React.StrictMode>
);

完成!你现在可以用类型安全的方式在各种地方调用对话框组件了

App.tsx

import { Button, Space } from "antd";
import { dialog } from "./lib/dialog";

const App: React.FC = () => {
  const { open, close, isOpen } = dialog.useDialog("customDialog", {
    title: "标题",
    content: "内容"
  });

  return (
    <>
      <div>Dialog Status: {isOpen ? "open" : "closed"}</div>
      <Space>
        <Button type="primary" onClick={() => open()}>
          打开对话框
        </Button>
        <Button type="primary" onClick={() => close()}>
          关闭对话框
        </Button>
        <Button onClick={() => open({ title: "另一个标题" })}>
          打开另一个对话框
          {/* 此时对话框标题会改为“另一个标题” */}
        </Button>
      </Space>
    </>
  );
};

export default App;

更多

更多使用文档,请见GitHub Readme

API文档:github.com/jsun969/rea…

求Star 🌟🌟🌟