React 简单介绍

本文深入探讨了React框架的设计理念及其核心特点,包括Virtual DOM、组件化结构及数据流管理。介绍了React如何解决大型应用中数据频繁变化的问题,并通过实例展示了React的基本使用。

React是Facebook开发的一款JS库,那么Facebook为什么要建造React呢,主要为了解决什么问题,通过这个又是如何解决的?

从这几个问题出发我就在网上搜查了一下,有这样的解释。

Facebook认为MVC无法满足他们的扩展需求,由于他们非常巨大的代码库和庞大的组织,使得MVC很快变得非常复复杂,每当需要添加一项新的功能或特性时,系统的复杂度就成级数增长,致使代码变得脆弱和不可预测,结果导致他们的MVC正在土崩瓦解。认为MVC不适合大规模应用,当系统中有很多的模型和相应的视图时,其复杂度就会迅速扩大,非常难以理解和调试,特别是模型和视图间可能存在的双向数据流动。

解决这个问题需要“以某种方式组织代码,使其更加可预测”,这通过他们(Facebook)提出的Flux和React已经完成。

Flux 是一个系统架构,用于推进应用中的数据单向流动。 React 是一个JavaScript框架,用于构建“可预期的”和“声明式的”Web用户界面,它已经使Facebook更快地开发Web应用

对于Flux,目前还没怎么研究,不怎么懂,这里就先把Flux的图放上来,有兴趣或者了解的可以再分享下,这里主要说下React。

Flux Flux

那么React是解决什么问题的,在官网可以找到这样一句话:

We built React to solve one problem: building large applications with data that changes over time.

构建那些数据会随时间改变的大型应用,做这些,React有两个主要的特点:

  1. 简单 
    简单的表述任意时间点你的应用应该是什么样子的,React将会自动的管理UI界面更新当数据发生变化的时候。
  2. 声明式 
    在数据发生变化的时候,React从概念上讲与点击了F5一样,实际上它仅仅是更新了变化的一部分而已。 
    React是关于构造可重用组件的,实际上,使用React你做的仅仅是构建组建。通过封装,使得组件代码复用、测试以及关注点分离更加容易。

另外在React官网上,通过《 Why did we build React? 》为什么我们要建造React的文档中还可以了解到以下四点:

  • React不是一个MVC框架
  • React不使用模板
  • 响应式更新非常简单
  • HTML5仅仅是个开始

具体也可以看我前面一篇文章《 为什么我们要造React? 》。

React主要的原理

Virtual DOM 虚拟DOM

传统的web应用,操作DOM一般是直接更新操作的,但是我们知道DOM更新通常是比较昂贵的。而React为了尽可能减少对DOM的操作,提供了一种不同的而又强大的方式来更新DOM,代替直接的DOM操作。就是 Virtual DOM ,一个轻量级的虚拟的DOM,就是React抽象出来的一个对象,描述dom应该什么样子的,应该如何呈现。通过这个Virtual DOM去更新真实的DOM,由这个Virtual DOM管理真实DOM的更新。

为什么通过这多一层的Virtual DOM操作就能更快呢? 这是因为React有个diff算法,更新Virtual DOM并不保证马上影响真实的DOM,React会等到事件循环结束,然后利用这个diff算法,通过当前新的dom表述与之前的作比较,计算出最小的步骤更新真实的DOM。

virtual DOM virtual DOM

Components 组件

在DOM树上的节点被称为元素,在这里则不同,Virtual DOM上称为commponent。Virtual DOM的节点就是一个完整抽象的组件,它是由commponents组成。

component 的使用在 React 里极为重要, 因为 components 的存在让计算 DOM diff 更高效。

State 和 Render

React是如何呈现真实的DOM,如何渲染组件,什么时候渲染,怎么同步更新的,这就需要简单了解下State和Render了。state属性包含定义组件所需要的一些数据,当数据发生变化时,将会调用Render重现渲染,这里只能通过提供的setState方法更新数据。

好了,说了这么多,下面看写代码吧,先看一个官网上提供的 Hello World 的示例:

<!DOCTYPE html><html><head><script src="http://fb.me/react-0.12.1.js"></script><script src="http://fb.me/JSXTransformer-0.12.1.js"></script></head><body><div id="example"></div><script type="text/jsx">React.render(<h1>Hello, world!</h1>,document.getElementById('example'));</script></body></html>

这个很简单,浏览器访问,可以看到 Hello, world! 字样。 JSXTransformer.js 是支持解析JSX语法的,JSX是可以在Javascript中写html代码的一种语法。如果不喜欢,React也提供原生Javascript的方法。

再来看下另外一个例子:

<html>	<head>		<title>Hello React</title>		<script src="http://fb.me/react-0.12.1.js"></script>		<script src="http://fb.me/JSXTransformer-0.12.1.js"></script>		<script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>		<script src="http://cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>		<style>		#content{			width: 800px;			margin: 0 auto;			padding: 5px 10px;			background-color:#eee;		}		.commentBox h1{			background-color: #bbb;		}		.commentList{			border: 1px solid yellow;			padding:10px;		}		.commentList .comment{			border: 1px solid #bbb;			padding-left: 10px;			margin-bottom:10px;		}		.commentList .commentAuthor{			font-size: 20px;		}		.commentForm{			margin-top: 20px;			border: 1px solid red;			padding:10px;		}		.commentForm textarea{			width:100%;			height:50px;			margin:10px 0 10px 2px;		}		</style>	</head>	<body>		<div id="content"></div>		<script type="text/jsx">		var staticData = [			{author: "张飞", text: "我在写一条评论~!"},			{author: "关羽", text: "2货,都知道你在写的是一条评论。。"},			{author: "刘备", text: "哎,咋跟这俩逗逼结拜了!"}		];		var converter = new Showdown.converter();//markdown		/** 组件结构:			<CommentBox>				<CommentList>					<Comment />				</CommentList>				<CommentForm />			</CommentBox>		*/		//评论内容组件		var Comment = React.createClass({			render: function (){				var rawMarkup = converter.makeHtml(this.props.children.toString());				return (					<div className="comment">						<h2 className="commentAuthor">							{this.props.author}:						</h2>						<span dangerouslySetInnerHTML={{__html: rawMarkup}} />					</div>				);			}		});		//评论列表组件		var CommentList = React.createClass({			render: function (){				var commentNodes = this.props.data.map(function (comment){					return (						<Comment author={comment.author}>							{comment.text}						</Comment>					);				});				return (					<div className="commentList">						{commentNodes}					</div>				);			}		});		//评论表单组件		var CommentForm = React.createClass({			handleSubmit: function (e){				e.preventDefault();				var author = this.refs.author.getDOMNode().value.trim();				var text = this.refs.text.getDOMNode().value.trim();				if(!author || !text){					return;				}				this.props.onCommentSubmit({author: author, text: text});				this.refs.author.getDOMNode().value = '';				this.refs.text.getDOMNode().value = '';				return;			},			render: function (){				return (					<form className="commentForm" onSubmit={this.handleSubmit}>						<input type="text" placeholder="Your name" ref="author" /><br/>						<textarea type="text" placeholder="Say something..." ref="text" ></textarea><br/>						<input type="submit" value="Post" />					</form>				);			}		});		//评论块组件		var CommentBox = React.createClass({			loadCommentsFromServer: function (){				this.setState({data: staticData});				/*				方便起见,这里就不走服务端了,可以自己尝试				$.ajax({					url: this.props.url + "?_t=" + new Date().valueOf(),					dataType: 'json',					success: function (data){						this.setState({data: data});					}.bind(this),					error: function (xhr, status, err){						console.error(this.props.url, status, err.toString());					}.bind(this)				});				*/			},			handleCommentSubmit: function (comment){				//TODO: submit to the server and refresh the list				var comments = this.state.data;				var newComments = comments.concat([comment]);				//这里也不向后端提交了				staticData = newComments;				this.setState({data: newComments});			},			//初始化 相当于构造函数			getInitialState: function (){				return {data: []};			},			//组件添加的时候运行			componentDidMount: function (){				this.loadCommentsFromServer();				this.interval = setInterval(this.loadCommentsFromServer, this.props.pollInterval);			},			//组件删除的时候运行			componentWillUnmount: function() {				clearInterval(this.interval);			},			//调用setState或者父级组件重新渲染不同的props时才会重新调用			render: function (){				return (					<div className="commentBox">						<h1>Comments</h1>						<CommentList data={this.state.data}/>						<CommentForm onCommentSubmit={this.handleCommentSubmit} />					</div>				);			}		});		//当前目录需要有comments.json文件		//这里定义属性,如url、pollInterval,包含在props属性中		React.render(			<CommentBox url="comments.json" pollInterval="2000" />,			document.getElementById("content")		);		</script>	</body></html>

乍一看挺多,主要看脚本部分就可以了。方便起见,这里都没有走后端。定义了一个全局的变量 staticData ,可权当是走服务端,通过浏览器的控制台改变 staticData 的值,查看下效果,提交一条评论,查看下staticData的值的变化。

应用情况

国外应用的较多,facebook、Yahoo、Reddit等。在github可以看到一个列表 Sites-Using-React ,国内的话,查了查,貌似比较少,目前知道的有一个杭州大搜车。大多技术要在国内应用起来一般是较慢的,不过React确实感觉比较特殊,特别是UI的组件化和Virtual DOM的思想,我个人比较看好,有兴趣继续研究研究。

比较分析

和其他一些js框架相比,React怎样,比如Backbone、Angular等。

  • React不是一个MVC框架,它是构建易于可重复调用的web组件,侧重于UI, 也就是view层
  • 其次React是单向的从数据到视图的渲染,非双向数据绑定
  • 不直接操作DOM对象,而是通过虚拟DOM通过diff算法以最小的步骤作用到真实的DOM上。
  • 不便于直接操作DOM,大多数时间只是对 virtual DOM 进行编程
内容概要:本文是一篇关于使用RandLANet模型对SensatUrban数据集进行点云语义分割的实战教程,系统介绍了从环境搭建、数据准备、模型训练与测试到精度评估的完整流程。文章详细说明了在Ubuntu系统下配置TensorFlow 2.2、CUDA及cuDNN等深度学习环境的方法,并指导用户下载和预处理SensatUrban数据集。随后,逐步讲解RandLANet代码的获取与运行方式,包括训练、测试命令的执行与参数含义,以及如何监控训练过程中的关键指标。最后,教程涵盖测试结果分析、向官方平台提交结果、解读评估报告及可视化效果等内容,并针对常见问题提供解决方案。; 适合人群:具备一定深度学习基础,熟悉Python编程和深度学习框架,从事计算机视觉或三维点云相关研究的学生、研究人员及工程师;适合希望动手实践点云语义分割项目的初学者与进阶者。; 使用场景及目标:①掌握RandLANet网络结构及其在点云语义分割任务中的应用;②学会完整部署一个点云分割项目,包括数据处理、模型训练、测试与性能评估;③为参与相关竞赛或科研项目提供技术支撑。; 阅读建议:建议读者结合提供的代码链接和密码访问完整资料,在本地或云端环境中边操作边学习,重点关注数据格式要求与训练参数设置,遇到问题时参考“常见问题与解决技巧”部分及时排查。
内容概要:本文详细介绍了三相异步电机SVPWM-DTC(空间矢量脉宽调制-直接转矩控制)的Simulink仿真实现方法,结合DTC响应快与SVPWM谐波小的优点,构建高性能电机控制系统。文章系统阐述了控制原理,包括定子磁链观测、转矩与磁链误差滞环比较、扇区判断及电压矢量选择,并通过SVPWM技术生成固定频率PWM信号,提升系统稳态性能。同时提供了完整的Simulink建模流程,涵盖电机本体、磁链观测器、误差比较、矢量选择、SVPWM调制、逆变器驱动等模块的搭建与参数设置,给出了仿真调试要点与预期结果,如电流正弦性、转矩响应快、磁链轨迹趋圆等,并提出了模型优化与扩展方向,如改进观测器、自适应滞环、弱磁控制和转速闭环等。; 适合人群:电气工程、自动化及相关专业本科生、研究生,从事电机控制算法开发的工程师,具备一定MATLAB/Simulink和电机控制理论基础的技术人员。; 使用场景及目标:①掌握SVPWM-DTC控制策略的核心原理与实现方式;②在Simulink中独立完成三相异步电机高性能控制系统的建模与仿真;③通过仿真验证控制算法有效性,为实际工程应用提供设计依据。; 阅读建议:学习过程中应结合文中提供的电机参数和模块配置逐步搭建模型,重点关注磁链观测、矢量选择表和SVPWM调制的实现细节,仿真时注意滞环宽度与开关频率的调试,建议配合MATLAB官方工具箱文档进行参数校准与结果分析。
已经博主授权,源码转载自 https://pan.quark.cn/s/bf1e0d5b9490 本文重点阐述了Vue2.0多Tab切换组件的封装实践,详细说明了通过封装Tab切换组件达成多Tab切换功能,从而满足日常应用需求。 知识点1:Vue2.0多Tab切换组件的封装* 借助封装Tab切换组件,达成多Tab切换功能* 支持tab切换、tab定位、tab自动化仿React多Tab实现知识点2:TabItems组件的应用* 在index.vue文件中应用TabItems组件,借助name属性设定tab的标题* 通过:isContTab属性来设定tab的内容* 能够采用子组件作为tab的内容知识点3:TabItems组件的样式* 借助index.less文件来设定TabItems组件的样式* 设定tab的标题样式、背景色彩、边框样式等* 使用animation达成tab的切换动画知识点4:Vue2.0多Tab切换组件的构建* 借助运用Vue2.0框架,达成多Tab切换组件的封装* 使用Vue2.0的组件化理念,达成TabItems组件的封装* 通过运用Vue2.0的指令和绑定机制,达成tab的切换功能知识点5:Vue2.0多Tab切换组件的优势* 达成多Tab切换功能,满足日常应用需求* 支持tab切换、tab定位、tab自动化仿React多Tab实现* 能够满足多样的业务需求,具备良好的扩展性知识点6:Vue2.0多Tab切换组件的应用场景* 能够应用于多样的业务场景,例如:管理系统、电商平台、社交媒体等* 能够满足不同的业务需求,例如:多Tab切换、数据展示、交互式操作等* 能够与其它Vue2.0组件结合运用,达成复杂的业务逻辑Vue2.0多Tab切换组件的封装实例提供了...
代码下载地址: https://pan.quark.cn/s/41cd695ddf65 `htmldiff` 是一个以 Ruby 语言为基础构建的库,其主要功能是在 HTML 文档中展示文本之间的差异。 该库的一个显著特点在于它不仅能够识别出不同之处,还会借助 HTML 标签来呈现这些差异,从而让用户能够直观地观察到文本的变化情况。 这种特性使得 `htmldiff` 在版本控制、文档对比或任何需要展示文本变动场景的应用中显得尤为有用。 `htmldiff` 的核心作用是对比两个字符串,并生成一个 HTML 输出结果,这个结果会明确地指出哪些部分被添加、哪些部分被删除以及哪些部分被修改。 此外,通过运用 CSS,用户可以进一步调整差异展示的样式,使其与项目或网站的现有设计风格相协调。 在使用 `htmldiff` 之前,需要先完成该库的安装。 如果项目已经配置了 Ruby 环境和 Gemfile,可以在 Gemfile 文件中添加 `gem htmldiff` 语句,随后执行 `bundle install` 命令进行安装。 如果没有 Gemfile 文件,也可以直接采用 `gem install htmldiff` 命令来进行全局安装。 在编程实现时,可以通过调用 `Htmldiff.diff` 方法来对比两个字符串,并获取相应的 HTML 输出。 例如:```rubyrequire htmldiffstr1 = "这是一个示例文本。 "str2 = "这是一个示例文本,现在有更多内容。 "diff_html = Htmldiff.diff(str1, str2)puts diff_html```上述代码将会输出两个字符串之间的差异,其中新增的内容会被 `<ins>` 标签所包围,而...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值