网站基础建设英文翻译,网站编程基础,WordPress占资源多,app开发哪个公司好前言
在之前学vue2的时候封装过一个全局的弹窗组件#xff0c;可以全局任意地方通过this调用#xff0c;这次大创项目是用react技术栈#xff0c;看了一下项目需求#xff0c;突然发现弹窗还是比较多的#xff0c;主要分为基础的弹窗以及form表单式的弹窗#xff0c;如果…前言
在之前学vue2的时候封装过一个全局的弹窗组件可以全局任意地方通过this调用这次大创项目是用react技术栈看了一下项目需求突然发现弹窗还是比较多的主要分为基础的弹窗以及form表单式的弹窗如果只是无脑的去写代码那些项目也没啥必要了。正好react和hook相结合去实现一个全局的弹窗组件便于之后的使用。
心血历程
antd组件的弹窗一般是和我们的代码放一起的这样就导致复用性比较低而且也显得代码比较乱。由此我就想过自己封装一个有了之前使用vue封装的经验我开始着手封装基本思路就是创建一个新的div放到页面中手动的渲染与删除确定和取消按钮正好对应promise的成功与失败。基本思路没有问题但是再实行的过程中首先遇到手动渲染挂载到页面的问题之后又遇到逻辑放到一起无法手动控制form表单最后突然想清楚一点就是逻辑可以分开把一个功能的相同点与不同点进行分离逻辑上要单纯最后再整合到一起。这样的话可以专注于具体的逻辑功能及实现。
代码
modal.tsx
封装的弹窗具体功能,其中根据类型的不同会用到form的高阶组件
import React, { useCallback, useEffect } from react;
import ReactDOM from react-dom/client;
import { Button, Modal } from antd;
import { useState } from react;
import { useForm } from ./form;
type PromiseType {resolve?: any;reject?: any;
};
// modal类型(分为普通或者表单形式)
type modalType nomal | form;
/*
成功之后的回调函数
显示标题
提示文字(用于普通类型文本提示)
成功文字
配置对象(字段名规则默认值)
*/
type modalPropsType {type?: modalType;title?: string;infoTxt?: string;okTxt?: string;successCallback?: (values?: any) void;formOptions?: any;
};export const useModal (props: modalPropsType {}) {const {type nomal,title 提示,infoTxt 这是一段提示,okTxt 确定,successCallback () {},formOptions [],} props;const [show, setShow] useStateboolean(false);const [promiseRes, setPromiseRes] useStatePromiseType();const [containerEle, setContainerEle] useStateHTMLElement | null(null);// 节点的挂载与卸载useEffect(() {if (containerEle) {return;}// 创建挂载节点const div document.createElement(div);div.id myContainer;document.body.append(div);setContainerEle(div);}, [containerEle]);// 卸载节点const unMounted useCallback(() {if (containerEle) {document.body.removeChild(containerEle);setContainerEle(null);}}, [containerEle]);const success useCallback((values: any) {successCallback successCallback();promiseRes?.resolve(type nomal ? 确定 : values);setShow(false);unMounted();},[promiseRes, unMounted, successCallback, type],);// 取消const cancel useCallback(() {promiseRes?.reject(取消);setShow(false);unMounted();}, [unMounted, promiseRes]);// 获取包装节点const { MyForm } useForm({ cancel, success, okTxt, options: formOptions });// 挂载节点useEffect(() {if (!show || !containerEle) {return;}const root ReactDOM.createRoot(containerEle as HTMLElement);// 根据类型去判断是简单的弹窗还是form表单root.render(ModalonCancel{cancel}open{show}onOk{success}destroyOnClose{true}title{title}okText{okTxt}wrapClassNamemodal-wrapcancelButtonProps{{ shape: round }}okButtonProps{{ shape: round }}width{600}footer{type form? null: [Button keysuccess typeprimary onClick{success}{okTxt}/Button,Button keycancel onClick{cancel}取消/Button,]}getContainer{containerEle as HTMLElement}{type form MyForm/MyForm}{type nomal p{infoTxt}/p}/Modal,);}, [show,MyForm,cancel,containerEle,title,infoTxt,okTxt,success,type,]);// 初始化const init () {setShow(true);return new Promise((resolve, reject) {setPromiseRes({ resolve, reject });});};return { init };
};from.tsx
封装的form表单待完善
import { Button, Form, FormInstance, Input, Space } from antd;
import React from react;
import { useCallback } from react;/*
传递配置对象()
1. 成功回调
2.失败回调
3.配置对象自动生成form表单
*/
type formProp {success: (values: any) void;cancel: () void;okTxt: string;options?: any;
};type FieldType {username?: string;password?: string;remember?: string;
};
export const useForm (formProp: formProp) {const { success, cancel, okTxt } formProp;const MyForm () {const formRef React.useRefFormInstance(null);const onFinish useCallback((values: any) {console.log(values);success(values);}, []);const onFinishFailed useCallback((values: any) {console.log(values);}, []);const onReset () {formRef.current?.resetFields();};return (Formref{formRef}labelCol{{ span: 8 }}wrapperCol{{ span: 16 }}style{{ maxWidth: 600 }}initialValues{{ remember: true }}autoCompleteoffonFinish{onFinish}onFinishFailed{onFinishFailed}Form.ItemFieldTypelabelUsernamenameusernamerules{[{ required: true, message: Please input your username! }]}Input //Form.ItemForm.ItemFieldTypelabelPasswordnamepasswordrules{[{ required: true, message: Please input your password! }]}Input.Password //Form.ItemForm.Item wrapperCol{{ offset: 8, span: 16 }}Space wrapButton typeprimary htmlTypesubmit{okTxt}/ButtonButton danger htmlTypebutton onClick{onReset}重置/ButtonButton onClick{cancel}取消/Button/Space/Form.Item/Form);};return {MyForm,};
};
使用
//可以传递type来指定类型
const nomalMadaluseModal()
//执行该函数开启弹窗
const show(){nomalMadal.init().then((res) {console.log(确定, res);}).catch((err) {console.log(取消, err);});
}总结
在之后的学习过程中要多换思路不必拘谨于一个点要把思维发散逻辑可以多种方法实现还有就是源码的能力之后要多学一下源码了解源码的思想还有实现方法这样才能更好的玩转第三方库如果只是简单的使用那一个小白培训个几个月也能达到使用的程度要有自己的见解和自己的优势。