命令式调用你的 React web 组件

发布于 2022-11-23 14:11:24 字数 3457 浏览 137 评论 0

大多数时候,是这样使用 React 组件的:

通过显示地修改传递给组件的 props 来改变组件的状态(显隐、颜色、内容等),这在大多数时候非常好用,并且这就是 React 的设计哲学,这属于声明式调用,但考虑一下我们经常用到的弹框组件(toast、modal、loading),因为弹框组件会被经常调用,并且可能同时存在多个实例,这样就需要维护多个props的状态,同时还需要手动修改父组件的 state 来控制显隐,这是非常繁琐的。

类似于 antd 的message 的使用方式 message.info('This is a normal message') ,antd 称其为全局提示组件。

这种调用方式就是命令式调用,这种调用方式非常类似于以往 jQuery 时代的js库,好处在于不再需要不断地维护 组件 的状态,这对于 toastmodalloading 来说非常有用。

其实设计这样一个组件并不难,其核心在于主动调用 ReactDOM.render 方法,将组件渲染上去,以设计一个 toast info 组件为例:

首先编写普通的 react 组件:

import React from 'react'
import ReactDOM from 'react-dom'

export interface InfoProps {
	/**
	 * 提示消息
	 */
	msg: string
	/**
	 * 图标类型,none,info,fail,success
	 * 默认为 none
	 */
	icon?: string
}

export default class Info extends React.Component<InfoProps, any> {
	public defaultProps: InfoProps = {
		msg: '',
		icon: 'none'
	}

	render() :React.ReactNode{
		const { icon, msg } = this.props
		const showIcon = icon !== 'none'
		const iconClass = `icon ${icon !== 'info' ? 'icon_' + icon : ''}`
		return (
			<div className="mod_alert_v2 show fixed">
				{showIcon ? <i className={iconClass} /> : null}
				<p>{msg}</p>
			</div>
		)
	}
}

暴露一个普通方法,来手动挂载到页面上去

import React from 'react'
import ReactDOM from 'react-dom'
import Info, { InfoProps } from './Info'

export default function info(
	opts: InfoProps & {
		/**
		 * 计时消失毫秒数,默认 2000
		 */
		delay?: number
		/**
		 * 是否显示蒙层
		 * 默认不显示
		 */
		showcoverdiv?: boolean
	} = {
		msg: ''
	}
) {
	const options = Object.assign(
		{
			msg: '',
			delay: 2000,
			icon: 'none',
			showcoverdiv: false
		},
		opts
	)

	const div = document.createElement('div')
	document.body.appendChild(div)
	ReactDOM.render(<Info msg={options.msg} icon={options.icon} />, div)

	setTimeout(() => {
		ReactDOM.unmountComponentAtNode(div)
		document.body.removeChild(div)
	}, options.delay)
}

其核心就是通过 ReactDOM.render 来挂载上去的,通过 ReactDOM.unmountComponentAtNode 来卸载组件的。

简单的调用方式如下:

通过这种方式,可以很快地封装好你的 React 命令式组件,以个人经验而言,对于 web 常用的 toastmodalloading 这三种组件应该是封装为这种组件会更加方便使用的。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

0 文章
0 评论
21 人气
更多

推荐作者

lioqio

文章 0 评论 0

Single

文章 0 评论 0

禾厶谷欠

文章 0 评论 0

alipaysp_2zg8elfGgC

文章 0 评论 0

qq_N6d4X7

文章 0 评论 0

放低过去

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文