React: 研究React的组件化
一、简介大概
在以往的Web开发中,会把web页面所有的复杂控件作为一个单一的整体进行开发,由于控件之间需要进行通信,因此不同的组件之间的耦合度会很多,由于开发一个控件的时候要考虑到控件与控件之间的联系,这么一来,随意一个复杂控件的代码思想就很复杂。ReactJS的出现,很好地解决了这个问题,ReactJS的核心思想就是组件化,它会把页面中的组件一个个进行分解,按照功能要求,大组件可以分解成小组件,小组件还可以分解成更小更简单的组件,各个组件维护自己的状态和UI,当状态发生改变时,会自动重现渲染整个组件,多个组件一起协作共同构成了ReactJS应用。组件化的开发思想中,可以将组件对应一个类,类与类之间的组合实现了解耦,而且类中将界面逻辑和业务逻辑统一在一起又实现了聚合,逻辑很直观。
二、简单创建
在ReactJS中,React为开发者提供了丰富的API,详细的可以去官网查看:http://facebook.github.io/react/docs/getting-started.html。当然,在日常开发中常用的API主要分为两大类,分别是顶层API和组件API。
顶层API:挂在React对象下的API,如React.createClass、React.render、ReactDOM.render等。
组件API:只有组件内部才可以调用的API,如render等。
创建一个简单的组件如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Hello React</title>
<script src="react.js"></script>
<script src="react-dom.js"></script>
<script src="browser.min.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/babel">
var DivComponment = React.createClass({
render: function(){
return (
<div>Hello DivComponment!!!</div>
);
}
});
ReactDOM.render(
<DivComponment></DivComponment>,
document.getElementById('container') /*document.querySelector('#container')*/
);
</script>
</body>
</html>
渲染结果如下:
注意:React.render已过时,推荐用ReactDOM.render。
三、步骤详解
1、React是全局对象,ReactJS的所有顶层API都挂在这个对象下;
2、React.createClass是ReactJS用来创建组件类的方法;
3、render是一个组件级别的API,是React.createClass内部最常用的API,该方法主要用来返回组件结构;
4、ReactDOM.render是最基本的方法,用于将模板转为HTML,并将转换后的DMO结构插入到指定的DOM节点上。
5、ReactDOM.render函数可以拥有三个参数,第1个参数是ReactJs组件,第2个参数是组件挂载的父节点容器,第3个则是插入后的函数回调。格式:
//基本格式
ReactDOM.render (
ReactElement element, //ReactJS组件
DOMElement container, //页面中的DOM容器,也即挂载节点
[function callback] //插入后的回调
)
四、生命周期
使用ReactJS创建的组件也是存在生命周期的,这个生命周期贯穿在render方法前后,在这个过程中,开发者可以处理需要的业务逻辑。组建的声明周期主要分为四个阶段,分别是创建阶段、实例化阶段、更新阶段、销毁阶段。
现在,咱们就来监控一下创建一个组建的生命周期是如何运作的。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Hello React</title>
<script src="react.js"></script>
<script src="react-dom.js"></script>
<script src="browser.min.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/babel">
var DivComponent = React.createClass({ //1.创建阶段
getDefaultProps() {
//在创建组件类的时候被调用, 对this.props进行初始化
console.log("------getDefalutProps------");
return {
title:"I Am XYQ"
}
}, //2.实例化阶段
getInitialState() {
//给this.state进行初始化
console.log("------getInitialState------");
return {
val : 1
}
}, componentWillMount() {
//根据业务逻辑对state进行相应的操作
var message = "------componentWillMount------";
if(this.state.val == 1){
message = message + "this.state.val = " + this.state.val;
}
console.log(message);
}, render:function() {
//渲染返回一个虚拟的DOM
console.log("------render------");
return (
<div>{this.props.title}</div>
);
}, componentDidMount() {
//创建真实的DOM结构
console.log("------componentDidMount------");
this.setState({
val: this.state.val + 1
})
setTimeout(() => {
this.setState({val: this.state.val + 1});
}, 0); //方式一:修改DOM节点元素的样式, 该方法已过时,推荐使用方式二
//this.getDOMNode().style.color = "red"
//this.getDOMNode().style.fontSize = "30px" //方式二:修改DOM节点元素的样式,ReactDOM.findDOMNode(instance)
var div = document.getElementById('container')
ReactDOM.findDOMNode(div).style.color = "red";
ReactDOM.findDOMNode(div).style.fontSize = "30px";
}, //3.更新阶段
componentWillReceiveProps(nextProps) {
//发生在this.props被修改或父组件调用setProps()时调用
console.log("------componentWillReceiveProps------"+"nextProps.title = "+nextProps.title);
}, shouldComponentUpdate(nextProps, nextState) {
//是否更新
console.log("------shouldComponentUpdate------"+"nextProps.title = "+nextProps.title + "-----" +"nextState.val = "+nextState.val);
return true;
}, componentWillUpdate() {
//将要更新
console.log("------componentWillUpdate------");
}, componentDidUpdate() {
//更新完毕
console.log("------componentDidUpdate------");
}, //4.销毁阶段
componentWillUnmount() {
//销毁时调用
console.log("------componentWillUnmount------");
} });
ReactDOM.render(
<DivComponent/>,
document.getElementById('container') /*document.querySelector('#container')*/
); </script>
</body>
</html>
结果如下:
五、流程分析
1、关键词
state: 组件的属性,用来存储组件自身需要的数据
它是可以改变的,它的改变会引发组件的更新,这就是ReactJS的关键点之一。 每次数据的更新都是通过修改state属性的值,然后ReactJS内部会监听state属性的变化,一旦发生变化,就会主动触发组件的render方法来更新DOM结构
虚拟DOM: ReactJS中提出的概念
将真实的DOM结构映射成一个JSON数据结构
2、流程线
创建阶段:创建组件类,也即使用React.createClass()时
调用getDefalutProps返回一个对象并缓存,作为返回值跟父组件props合并,然后再赋值给this.props作为组件默认属性。
实例化阶段:对组件类进行实例化 ,也即使用ReactDOM.render()时
getInittialState: 初始化组件state的值,并作为返回值,赋值给组件的this.state属性
componentWillMount:根据业务逻辑对state进行相应的操作, 组件即将进行组装
render: 根据state的值,生成页面需要的虚拟DOM结构,并返回该结构
componentDidMount: 根据虚拟DOM结构生成真实的DOM进行处理,组件完成组装,内部可以使用this.getDOMNode()获取当前组件节点,然后进行操作,该方法已过时
更新阶段:根据用户的操作,对相应页面的调整进行组件更新
componentWillReceiveProps(nextProps):获取到新的props属性时调用,例如在该函数中调用this.state对state进行修改
shouldComponentUpdate(nextProps,nextState):该方法用来拦截新的prop或者state,根据逻辑判断来决定组件是否更新
componentWillUpdate:如果shouldComponentUpdate返回true决定更新,可以在该方法中做一些更新之前的操作,并且后面的componentDidUpdate才会执行
render:根据diff算法,对更新前后的结构进行比较,生成需要更新的虚拟的DOM数据。推荐,该方法中只做数据和模板组合,不做state等逻辑修改
componentDidUpdate: 该方法在组件更新同步到DOM后调用,可以对DOM进行一些操作
销毁阶段:
componentWillUnmount: 组件从DOM中移除时会调用。一般在该方法中做一些取消事件绑定、销毁定时器等。
六、组件通信
虽然说ReactJS的数据流是单向的,但是ReactJS仍然提供了组件之间进行双向通信的方式,可以通过系统默认的属性关键字来实现。
这两个属性关键字分别是props和ref。
- 子组件调用父组件的方法:父组件把被调用的的方法以属性的形式放在子组件上,子组件通过“this.props.被调用方法”方式进行调用
- 父组件调用子组件的方法:子组件被设置一个ref属性,父组件可以通过“this.ref.xxx”方式拿到子组件,然后进行相应的设置和逻辑处理
如下示例:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Hello React</title>
<script src="react.js"></script>
<script src="react-dom.js"></script>
<script src="browser.min.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/babel"> //父组件
//通过子组件的ref属性获取子组件并设置子组件样式
var Parent = React.createClass({ render:function() { //给div添加点击事件,切换字体颜色
function testClick(){ var childDOM = ReactDOM.findDOMNode(this.refs.child); if(childDOM.style.color == "red"){
childDOM.style.color = "green";
}
else if(childDOM.style.color == "green"){
childDOM.style.color = "red";
}
else {
childDOM.style.color = "red";
}
childDOM.style.fontSize = "30px";
} return (
<div onClick={testClick.bind(this)}>
Parent is:
<Children name={this.props.name} ref="child"></Children>
</div>
)
}
}); //子组件
//通过父组件的this.props.name设置子组件属性值
var Children = React.createClass({
render:function() {
return (
<h1> {this.props.name} </h1>
)
}
}); ReactDOM.render(
<Parent name="I Am XYQ"></Parent>,
document.getElementById('container')
); </script>
</body>
</html>
React: 研究React的组件化的更多相关文章
- 使用 webpack + react + redux + es6 开发组件化前端项目
因为最近在工作中尝试了 webpack.react.redux.es6 技术栈,所以总结出了一套 boilerplate,以便下次做项目时可以快速开始,并进行持续优化.对应的项目地址:webpack- ...
- 从DOM操作看Vue&React的前端组件化,顺带补齐React的demo
前言 接上文:谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo 上次写完博客后,有朋友反应第一内容有点深,看着迷迷糊糊:第二是感觉没什么使用场景,太过业务化,还不如直接写Vue ...
- 谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo
前言 前端已经过了单兵作战的时代了,现在一个稍微复杂一点的项目都需要几个人协同开发,一个战略级别的APP的话分工会更细,比如携程: 携程app = 机票频道 + 酒店频道 + 旅游频道 + ..... ...
- 移动web端的react.js组件化方案
背景: 随着互联网世界的兴起,web前端开发的方式越来越多,出现了很多种场景开发的前端架构体系,也对前端的要求日益增高,早已经不是靠一个JQuery.js来做前端页面的时代了,而今移动端变化最大,近 ...
- client高性能组件化框架React简单介绍、特点、环境搭建及经常使用语法
[本文源址:http://blog.csdn.net/q1056843325/article/details/54729657 转载请加入该地址] 明天就是除夕了 预祝大家新春快乐 [ ]~( ̄▽ ̄) ...
- 【前端知识体系-JS相关】组件化和React
1. 说一下使用jQuery和使用框架的区别? 数据和视图的分离,(jQuery数据和视图混在一起,代码耦合)-------开放封闭原则 以数据驱动视图(只关注数据变化,DOM操作被封装) 2.说一下 ...
- 小谈React、React Native、React Web
React有三个东西,React JS 前端Web框架,React Native 移动终端Hybrid框架,React Web是一个源码转换工具(React Native 转 Web,并之所以特别提出 ...
- iOS开发之组件化架构漫谈
前段时间公司项目打算重构,准确来说应该是按之前的产品逻辑重写一个项目.在重构项目之前涉及到架构选型的问题,我和组里小伙伴一起研究了一下组件化架构,打算将项目重构为组件化架构.当然不是直接拿来照搬,还是 ...
- React Native 之 组件化开发
前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...
随机推荐
- SpringCloud之Feign:REST客户端
在Spring Cloud集群中,各个角色的通信基于REST服务,在调用服务时,需要使用REST客户端,常用,除了使用Spring自带的RestTemplate,也可使用另一个REST客户端:Feig ...
- Python 基础语法-str
字符串常见操作 find:检测str是否包含在 mystr 中,如果是返回开始的索引值,否则返回 -1 mystr.index(str, start=0, end=len(mystr)) count: ...
- Red Hat Enterprise Linux 官方正式版镜像下载
Red Hat Enterprise Linux是美国红帽公司开发的商业市场导向的Linux发行版,为方便大家学习研究,整理分享历代红帽官方正式版镜像给有需要的朋友们. 下载地址:https://ww ...
- python 实现 PC 客户端自动化快速入门:pywinauto !
本文转载自:http://www.lemfix.com/topics/420 一.前言 我们柠檬班的小可爱,在学完我们柠檬班自动化的课程之后,就掌握了接口自动化,web自动化,app自动化,这些工 ...
- Spring源码解析-ioc容器的设计
Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...
- HTML和css常见问题解答2
1.将一个块级元素水平和垂直居中有几种方法?分别是什么? 四种方式: (1).要让div等块级元素水平和垂直居中,必需知道该div等块级元素的宽度和高度,然后设置位置为绝对位置,距离页面窗口左边框和上 ...
- js对文中某一处关键字自动检索和全文检索
部分检索: 代码: <%@ page language="java" contentType="text/html; charset=utf-8" pag ...
- Yii2中$model->load($data)一直返回false问题
上次使用$model->load()方法时一直返回false,数据添加不成功,这里记录一下: 出错代码: $data = [ 'name' => 'test', 'phone' => ...
- docker cp命令出错问题
docker cp 4e6:/etc/nginx/nginx.conf /home/nginx/conf 使用docker在复制官方nginx容器的conf文件时,发生了错误. Error respo ...
- ASP.NET Core Web 应用程序系列(二)- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)
在上一章中主要和大家分享在MVC当中如何使用ASP.NET Core内置的DI进行批量依赖注入,本章将继续和大家分享在ASP.NET Core中如何使用Autofac替换自带DI进行批量依赖注入. P ...