相关文章推荐
严肃的跑步鞋  ·  React 使用 Proxy ...·  1 周前    · 
纯真的领结  ·  npm ...·  1 周前    · 
谦逊的硬币  ·  react ...·  1 周前    · 
傻傻的佛珠  ·  SpringBoot ...·  1 年前    · 
风流的奔马  ·  解决/usr/bin/pip: No ...·  1 年前    · 

React实现动态调用的弹框组件

作者:qq_35757537

这篇文章主要为大家详细介绍了React实现动态调用的弹框组件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

最近在用react开发项目,遇到一个需求——开发一个弹框组件。在react中创建一个组件是很简单的,只需要使用class创建并引入就可以了,但是要做到可以用js调用这个组件而不是写在jsx结构里,那就需要用到ReactDOM.render这个方法了。

首先先来屡一下需求:

1、弹框里的可配置字段:标题文字,提示文字,确认和取消按钮的显示隐藏以及文字。
2、点击确认和取消按钮后,可以触发相应的事件。
3、是否为短提示,短提示的时候,确认和取消按钮隐藏,并且2s后消失。

接下来用两种方法创建一个弹框组件,并比较一下这两种的差异。

下面先来实现一个普通的写在jsx结构里的组件:

弹框组件:DialogAlert.js

import React, { Component } from 'react';
import './index.scss';
class DialogAlert extends Component {
    constructor(props){
        super(props);
        this.state = {
            alertStatus:false,
            alertTitle:'提示', //标题
            alertTip:'网络错误', //提示
            cancelText:'取消',
            confirmText:'确认',
            isShortTip:false, //是否为短提示,短提示的情况下不显示'取消''确认'(且2s后消失),且优先级最高,其他配置无效
            isShowCancel:true, //是否显示确认按钮
            isShowConfirm:true, //是否显示确认按钮
            cancelCallbackFn:function(){}, //取消 回调函数
            confirmCallbackFn:function (){}//确认 回调函数
    componentWillReceiveProps(nextProps) {
        let options = nextProps.dialogOpt || {};
        //如果是短提示
        if(options.isShortTip){
            options.isShowCancel = false;
            options.isShowConfirm = false;
            setTimeout(()=>{
                this.close()
            },2000)
        this.setState({
            ...options
    cancel = () => {
        this.state.cancelCallbackFn();
        this.close()
    confirm = () => {
        this.state.confirmCallbackFn();
        this.close()
    close = () => {
        this.setState({
            alertStatus:false
    render(){
        let opts = this.state;
        return (
            <div className="dialog-wrap" style={opts.alertStatus ? {display:'block'}:{display:'none'}}>
                <div className="dialog-box">
                    <h6>{opts.alertTitle}</h6>
                    <p>{opts.alertTip}</p>
                    {!opts.isShowCancel && !opts.isShowConfirm ? null : (
                            {opts.isShowCancel ? (<span onClick={ () => this.cancel() }>{opts.cancelText}</span>) : null}
                            {opts.isShowConfirm ? (<span className="confirm" onClick={ () => this.confirm() }>{opts.confirmText}</span>) : null}
export default DialogAlert;

这里的数据更新用到了componentWillReceiveProps这个生命周期,当props发生变化时执行,初始化render时不执行,在这个回调函数里面,你可以根据属性的变化,通过调用this.setState()来更新你的组件状态,旧的属性还是可以通过this.props来获取,这里调用更新状态是安全的,并不会触发额外的render调用。

调用页面index.js

在state中定义可配置字段的变量

import DialogAlert from '../../widget/DialogAlert/index';
//省略了组件的js
this.state = {
    dialogOpt:{
        alertStatus:false,
        alertTip:'我是自定义的内容',
        cancelText:'取消2',
        confirmText:'确认2',
        isShortTip:false,
        isShowCancel:true, //是否显示确认按钮
        isShowConfirm:true, //是否显示确认按钮
        cancelCallbackFn:function(){
          alert(0);
        }, //取消 回调函数
        confirmCallbackFn:function (){
          alert(1);
        }//确认 回调函数
      //其他数据

在jsx中埋好对应的组件结构

<div onClick={()=>(this.alertdialog())}>点击触发弹框</div>
<DialogAlert dialogOpt={this.state.dialogOpt}></DialogAlert>

添加触发事件

alertdialog(){
    let opts = {
      alertStatus:true
    let _dialogOpt = Object.assign(this.state.dialogOpt,opts)
    this.setState({
      dialogOpt:_dialogOpt

这样就完成一个普通的弹框。总感觉这样写的一个组件弹框有点冗余,复用起来也比较麻烦——在state里配置所有自定义的变量,并改动jsx结构,还需要注意写入jsx结构时弹框的层级问题。

接下来我们来实现一种可动态调用的组件:

原理是创建一个div,并插入到body里面,用这个div当容器,使用render渲染组件,通过改变组件的state来控制组件的显示和隐藏。

弹框组件:DialogAlert.js

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.scss';
//调用方法
// DialogAlert.open({
    // alertTitle:'提示2',
    // alertTip:"页面加载失败,是否重新加载?",
    // cancelText:'取消',
    // confirmText:'重新加载',
    // isShortTip:true,
    // isShowCancel:true,
    // isShowConfirm:true,
    // cancelCallbackFn:function(){
    //   console.log('取消了')
    // },
    // confirmCallbackFn:function (){
    //   console.log("确认了...");
// });
class DialogBox extends Component {
    constructor(props){
        super(props);
        this.state = {
            alertStatus: false, //是否显示提示框
            alertTitle:'提示', //标题
            alertTip:'网络错误', //提示
            cancelText:'取消',
            confirmText:'确认',
            isShortTip:false, //是否为短提示,短提示的情况下不显示'取消''确认'(且2s后消失),且优先级最高,其他配置无效
            isShowCancel:true, //是否显示确认按钮
            isShowConfirm:true, //是否显示确认按钮
            cancelCallbackFn:function(){}, //取消 回调函数
            confirmCallbackFn:function (){}//确认 回调函数
    //打开提示框
    open = (options) => {
        options = options || {};
        //如果是短提示
        if(options.isShortTip){
            options.isShowCancel = false;
            options.isShowConfirm = false;
            setTimeout(()=>{
                this.close()
            },2000)
        options.alertStatus = true;
        this.setState({
            ...options
    cancel = () => {
        this.state.cancelCallbackFn();
        this.close()
    confirm = () => {
        this.state.confirmCallbackFn();
        this.close()
    close = () => {
        this.setState({
            alertStatus:false
    render(){
        let opts = this.state;
        return (
            <div className="dialog-wrap" style={opts.alertStatus? {display:'block'}:{display:'none'}}>
                <div className="dialog-box">
                    <h6>{opts.alertTitle}</h6>
                    <p>{opts.alertTip}</p>
                    {!opts.isShowCancel && !opts.isShowConfirm ? null : (
                            {opts.isShowCancel ? (<span onClick={ () => this.cancel() }>{opts.cancelText}</span>) : null}
                            {opts.isShowConfirm ? (<span className="confirm" onClick={ () => this.confirm() }>{opts.confirmText}</span>) : null}
let div = document.createElement('div');
document.body.appendChild(div);
let DialogAlert = ReactDOM.render(<DialogBox /> ,div); //返回实例
export default DialogAlert;

调用页面index.js

import DialogAlert from '../../widget/DialogAlert/index';
//省略了组件的js
DialogAlert.open({
    alertTip:"加载失败,是否重新加载?",
    confirmText:'重新加载',
    cancelCallbackFn:()=>{
        window.history.back();
    confirmCallbackFn:()=>{
        //todo...

这里用到了ReactDOM.render,官方文档说这个方法目前会返回了对根组件实例的引用,所以我们可以调用到里面的open方法。但是官方文档中目前应该避免使用返回的引用,因为它是历史遗留下来的内容。为了以后的react更新迭代的兼容,我们可以省去动态插入组件的过程,改为写在jsx中,并设置ref,使用this.refs.xxx获取当前组件的实例,以便调用实例方法。

只需引入之后,直接调用就可以了。这样写的好处是解决了弹框的层级问题,也不用去改动jsx结构,其他页面复用起来更加方便快捷。

这两种方法在组件的定义上并没有很大的不同,只是在更新状态的时候有差异。第一种方法是在componentWillReceiveProps这个生命周期中监听父组件的值的变化再更新到state上,第二中方法是直接调用实例的open方法通过获取参数将值更新到state上。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
  • 关于react-router-dom路由入门教程
    关于react-router-dom路由入门教程
    2023-03-03
  • React组件的生命周期详解
    React组件的生命周期详解
    2023-03-03
  • React 远程动态组件实践示例详解
    React 远程动态组件实践示例详解
    2023-03-03
  • React调度系统Scheduler工作原理详解
    React调度系统Scheduler工作原理详解
    2023-03-03
  • React 远程动态组件实践示例详解
    React 远程动态组件实践示例详解
    2023-03-03
  • 通过示例源码解读React首次渲染流程
    通过示例源码解读React首次渲染流程
    2023-03-03
  • 一文详解如何React中实现插槽
    一文详解如何React中实现插槽
    2023-03-03
  • React SSR架构Streaming Render与Selective Hydration解析
    React SSR架构Streaming Render与Selectiv
    2023-03-03
  • 美国设下计谋,用娘炮文化重塑日本,已影响至中国
    美国设下计谋,用娘炮文化重塑日本,已影响至中国
    2021-11-19
  • 时空伴随者是什么意思?时空伴随者介绍
    时空伴随者是什么意思?时空伴随者介绍
    2021-11-09
  • 工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    2021-11-05
  • 2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2021-10-26
  • 电脑版 - 返回首页

    2006-2023 脚本之家 JB51.Net , All Rights Reserved.
    苏ICP备14036222号