React反模式 —— 如何不使用JSX地动态显示组件
欢迎指导与讨论 : )
前言
文章的最后能写出以 Modal.open( ) 这种调用形式,动态显示React对话框组件的写法(类似于ant design),同时涉及数据交互(数据能异步地返回给调用者)。笔者将和大家一起探讨这种写法的大概思路、难点,细节问题欢迎指出和补充。 O(∩_∩)O
本文Demo地址:https://github.com/Penggggg/react-model-demo
关于Angular-1的动态组件的思路的Demo地址:https://github.com/Penggggg/angular-component-practices
欢迎 Star ~
最终效果图
// 调用代码
import Model from './Model; onClick = ( ) => {
Model.show({ msg: 'Are you a Man?', title: 'Hello!' })
.then(( value: string ) => {
// 点击Yes按钮后返回的数据
console.log(` value: ${value}`);
})
.catch( e => {
// 点击No按钮后返回的数据
console.log(`e`);
})
}

探讨1:如何不使用JSX也能显示React.Component实例
主要思路是:实例化一个组件 --> 渲染成Dom --> 插入到body元素内。
其中实例化与渲染成Dom可以使用ReactDom的render函数去完成: let _model = ReactDom.render(<Model />, div); 其中 div 是这个组件实例的一个容器(container dom),我们可以这样生产这个容器dom: let div = document.createElement('div'); 。最后只需要把渲染结果插入到body元素中: document.querySelector('body').appendChild( div );
// 组合起来就是
let div = document.createElement('div');
let _model = ReactDom.render(<Model />, div);
let dom = document.querySelector('body').appendChild(div);
探讨2:交互数据如何异步地返回给调用者
由于Modal组件涉及到数据交互(我们需要知道用户点击了Yes还是No),因此我们还需要将完成点击之后的数据异步地返回给调用者。同时,由于Modal的调用模式是 Modal.show( ) ,因此我决定在 Modal.show( ) 执行时,返回一个Promise给调用者
// 因此,整个调用模式看起来会像: Model.show( )
.then(( value: string ) => {
// 点击Yes后的代码(可以拿到数据value)
})
.catch( e => {
// 点击No后的代码
})
现在就剩下如何实现上面所说的了。
首先由于Modal是一个Class(类),因此我们需要把show函数作为Model 类的静态方法:
// Modal.js
export default class Model extends React.PureComponent{
static show( ) { // .... }
}
其次,我们需要返回一个实例的Promise,并且能够在Modal类方法地任意地方能够调用这个Promise实例 resolve( ) 和 reject( ) 方法从返回数据给调用者,因此我们把代码改动为
// Modal.js
export default class Model extends React.PureComponent{
_resolve;
_reject;
_promise = new Promise (( resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
})
static show( ) { // .... }
}
然后,为静态方法show( )函数加上一些逻辑:
// 静态方法show( )
static show( ) {
// 弹出成功!
let div = document.createElement('div');
let _model: any = ReactDom.render(<Model />, div);
let dom = document.querySelector('body').appendChild(div);
// 还记得我们需要return 一个promise吗
return _model._promise;
}
注意,这里的重点是:ReactDom.render( )会返回一个组件实例的js引用,而body.append( )会返回这个组件实例的dom引用,这两点很重要。
探讨3:点击按钮执行返回数据
有了上面的代码,这部分的实现就容易多了。首先先在Model的render函数里面把对话框的基本结构写出来(JSX),然后是为Yes/No按钮<button >分别添加一个react的点击事件。
// Modal render函数
render( ) {
let { title, msg } = this.props;
return(
<div className="m_bg">
<div className="m_body">
<h3 className="title">{title}</h3>
<div className="msg">{ msg }</div>
<div className="box">
<a onClick={this.onNo}>No</a>
<a onClick={this.onYes}>Yes</a>
</div>
</div>
</div>
)
}
// Yes/No按钮点击后的处理函数
onNo = ( ) => {
// 点击No后,调用者收到'i choice no'数据
this._reject('i choice no');
}
onYes = ( ) => {
// 点击Yes后,调用者收到'i choice yes'数据
this._resolve('i choice yes');
}
探讨4:如何销毁无用的组件实例及其内存
点击完成后,Modal用处就不大了。那我们要怎么销毁这个组件实例,以在文档里面移除domj结果,并回收这个实例的内存呢。答案是ReactDom的unmountComponentAtNode函数

因此,我们需要在 onYes( ) 和 onNo( ) 里面继续添加相应的逻辑:
// 以onYes( ) 为例
onYes = ( ) => {
this._resolve('i choice yes');
// 销毁
ReactDom.unmountComponentAtNode( this._container );
this._dom.remove( );
}
// 其中:this._container 来自于这部分代码
// static show( )
let div = document.createElement('div');
let _model = ReactDom.render(<Model , div);
_model._container = div;
// 其中:this._dom 来自于这部分代码
// static show( )
let dom = document.querySelector('body').appendChild(div);
_model._dom = dom;
完,欢迎补充和指出问题。完整代码请参考上面地址 O(∩_∩)O
React反模式 —— 如何不使用JSX地动态显示组件的更多相关文章
- react 反模式——不使用jsx动态显示异步组件
前言: react反模式 (anti-patterns)指的是违背react思想(flux)的coding方式. 本文在 App 组件中,通过 Model.show 动态显示 Model 组件,通过 ...
- React的JSX语法及组件
最近一个同事很急没有做任何交接就请了陪产假,然后我来维护.说实在的我一开始是一脸懵逼的.因为MV*项目里用的最多的还是Vue:React听说也了解过,但毕竟不熟... 不过不管如何这也是工作:同事也恭 ...
- React学习笔记-2-什么是jsx?如何使用jsx?
什么是jsx? JSX是JavaScript XML 这两个单词的缩写,xml和html非常类似,简单来说可以把它理解成使用各种各样的标签,大家可以自行 百度.所以jsx就是在javascri ...
- Python编程中的反模式
Python是时下最热门的编程语言之一了.简洁而富有表达力的语法,两三行代码往往就能解决十来行C代码才能解决的问题:丰富的标准库和第三方库,大大节约了开发时间,使它成为那些对性能没有严苛要求的开发任务 ...
- 重构24-Remove Arrowhead Antipattern(去掉箭头反模式)
基于c2的wiki条目.Los Techies的Chris Missal同样也些了一篇关于反模式的post. 简单地说,当你使用大量的嵌套条件判断时,形成了箭头型的代码,这就是箭头反模式(arrow ...
- ORM 是一种讨厌的反模式
本文由码农网 – 孙腾浩原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! (“Too Long; Didn’t Read.”太长不想看,可以看这段摘要 )ORM是一种讨厌的反模式,违背 ...
- Apache Hadoop最佳实践和反模式
摘要:本文介绍了在Apache Hadoop上运行应用程序的最佳实践,实际上,我们引入了网格模式(Grid Pattern)的概念,它和设计模式类似,它代表运行在网格(Grid)上的应用程序的可复用解 ...
- 开发反模式 - SQL注入
一.目标:编写SQL动态查询 SQL常常和程序代码一起使用.我们通常所说的SQL动态查询,是指将程序中的变量和基本SQL语句拼接成一个完整的查询语句. string sql = SELECT * FR ...
- 开发反模式(GUID) - 伪键洁癖
一.目标:整理数据 有的人有强迫症,他们会为一系列数据的断档而抓狂. 一方面,Id为3这一行确实发生过一些事情,为什么这个查询不返回Id为3的这一行?这条记录数据丢失了吗?那个Column到底是什么? ...
随机推荐
- 让我们山寨一张Windows Azure Global的壁纸
用过国际版Azure的同学都见过一个显示了机器中主要信息的壁纸,而这个壁纸是通过Sysinternals的一款叫做bginfo来实现的,这款软件的好处是对于批量管理主(虚拟)机的管理员和使用方都很实用 ...
- React.js实现原生js拖拽效果及思考
一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...
- 8.JAVA之GUI编程键盘码查询器
程序使用说明: 1.本程序由于是java代码编写,所以运行需安装jdk并配置好环境变量. 2. 复制java代码到记事本内,另存为Keyboard_events.java: 3.复制批处理代码到记事本 ...
- SharePoint2013 显示网站菜单中设计管理器功能
当部署完SharePoint2013后,并创建了对应的网站集,就开始试图去按照企业VI(Visual Identity)来定制站点的布局.色彩.字体等等的页面元素.可是,在站点的设置菜单中,默认没有“ ...
- 在CentOS 7/6.5/6.4 中安装Java JDK 8(转载)
转载在CentOS 7/6.5/6.4 中安装Java JDK 8 首先,在你的服务器上运行一下更新. yum update 然后,在您的系统上搜索,任何版本的已安装的JDK组件. rpm -qa | ...
- 数据库插入数据返回当前主键ID值方法
当我们插入一条数据的时候,我们很多时候都想立刻获取当前插入的主键值返回以做它用.我们通常的做法有如下几种: 1. 先 select max(id) +1 ,然后将+1后的值作为主键插入数据库: 2. ...
- C#的委托
之前本人一直在写一些相对比较基础的C#代码,现在做了一段时间项目了,遇到更麻烦的问题,比如今天要讨论的委托和事件,这个算是C#进阶篇的内容吧.现在自己就把这些天所学习的和自己所理解的和大家分享.有错请 ...
- C#连接Access与SQL Server
1.连接Access数据库 string strConnection = "Provider=Microsoft.Ace.OleDb.12.0; Data Source=" + S ...
- Hibernate4.2.4入门(一)——环境搭建和简单例子
一.前言 发下牢骚,这段时间要做项目,又要学框架,搞得都没时间写笔记,但是觉得这知识学过还是要记录下.进入主题了 1.1.Hibernate简介 什么是Hibernate?Hibernate有什么用? ...
- CSS3 border-radius 圆角属性
使用 CSS3 border-radius 属性,你可以给任何元素制作 "圆角". 浏览器支持 表格中的数字表示支持该属性的第一个浏览器的版本号. -webkit- 或 -moz- ...