React
React 是由Facfbook维护的一套框架,并且引用到instagram
React只是我们熟悉MVC框中的V层,只是视图层面的一个框架,只有俩个半api(createClass,createElement,render)
React与Angular的区别
React: 性能好,单向数据绑定,不是完整的框架。
Angular: 性能较差,双向数据绑定,是一套完整的框架
https://www.zhihu.com/question/23444167
为什么React的性能要好?
因为React做了俩点优化。
1、 在渲染时性能的优化
React是创建了一个虚拟dom,这个dom不是真正页面中的dom元素,它实质上是一个js对象,用js对象存储dom上的信息,因此比真是的dom小得多,因为他只记录的一些必要的信息。
操作一个虚拟dom需要的性能要远小于操作一个真实dom的性能,在前端开发一个web应用与开发一个网站不同,web应用通常是一个单页面,因此每次做一些交互会涉及各种dom操作,因此无节制的操作dom严重影响了页面的性能,但是我们只是操作虚拟dom会很好的降低对性能的消耗,在必要的时候将视图渲染到页面之中。
2、 在开发时的优化
React的开发理念是创建一个虚拟dom,而虚拟dom是一个js对象,它不是基于某一个端,比如真实的dom可能需要浏览器环境,它是基于web端的,所有通过React开发出来的组件可以用于任何平台,比如,服务器端,web端,ios端,android端
将虚拟dom引用到不同的端上需要不同的插件,然后调用不同的render方法。
|
学习React
- 认识React
- 组件
- Jsx的引用
- 插值符号
- 组件的属性
- 组件的样式
- 组件的事件
- 组件的生命周期
- React的ref属性
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8"/>
<title>hello react!</title>
</head>
<body>
<div id="root"></div>
<script src="js/react.min.js"></script>
<script src="js/react-dom.min.js"></script>
<script src="js/browser.min.js"></script>
<script type="text/babel">
console.dir(document.body)
console.log(<h1>hello,react!</h1>);
ReactDOM.render(
<h1>hello,react!</h1>,
document.getElementById("root")
);
</script>
</body>
</html>
认识React
1、 createElement()是用来创建虚拟dom的方法,他有一些参数
第一个参数表示:虚拟dom的名称,通常是一些标签名称,比如:div a p span
第二个参数表示:虚拟dom的属性,比如:className id title value
从第三个参数开始:表示虚拟dom的子节点。
2、 render()是用来将虚拟dom渲染到页面的方法
第一个参数表示:虚拟dom’元素
第二个参数表示:真是的dom元素
第三个参数表示:一个回调函数
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>非jsx编译时的创建虚拟dom</title> </head> <body> <div id="root"></div> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <!--<script src="js/browser.min.js"></script>--> <script type="text/javascript"> var virtualDOM=React.createElement( "ul", null, "我是ul", React.createElement( "li", null, "我是li1" ), React.createElement( "li", null, "我是li2" ), React.createElement( "li", null, "我是li3" ) ); ReactDOM.render( virtualDOM, document.getElementById("root") ); </script> </body> </html>
组件
1组件是做什么的?
如果一个虚拟dom复用多次的时候,通常我们将它封装在一个组件当中,通常用组件封装一组虚拟dom,这一组虚拟dom通常称他为虚拟dom树。
2组件如何创建?
createClass()是创建组件的方法,组件名称需要大写,参数是一个对象,对象中的属性和方法是对组件的说明:
属性1:render()方法,它是将组件中的虚拟dom输出,所以我们将虚拟dom定义在render()中并返回一个虚拟dom树。
Jsx语法引用
1.为什么引用jsx语法?
解决了创建虚拟dom成本过大的问题。
2.什么是jsx语法?
简单地说,就是jsx语法让我们可以再js中写xhtml
3.如何引用jsx语法?
- 引用一个库文件browser.min.js或者browser.js都行
- 在编写React的script标签的type属性为text/babel
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title></title> </head> <body> <div id="root"></div> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> <script type="text/babel"> var Ul=React.createClass({ render:function(){ return ( <ul name="哈哈"> 我是ul1 <li>我是li1</li> <li>我是li2</li> <li>我是li3</li> </ul> ) } }); var ul=React.createElement(Ul); ReactDOM.render( ul, document.getElementById("root") ); </script> </body> </html>
插值符号
- 什么是插值符号?
插值符号简单的说就是{},在jsx语法中书写注释需要写在插值符号中。
组件的属性
- props属性
1.props属性是什么?
和html给标签添加一个类一样,对于完全一致的统一组件他们暂时的样式是完全一致的,给其中一个添加一些属性,此时这个组件展示的结果就可能会不同,所以react提出了组件属性的概念。
2.如何添加props属性?
在jsx中为组件添加属性跟html中添加属性的方法是一模一样的,只不过react组件可以执行插值(就是可以将js中数据添加到组件中)
- state属性
1什么是无状态组件?
如果组建创建并渲染到页面中以后不会再更改,也就是说组件式一成不变的,这类组件我们只需要在创建之初为其添加一些属性即可完成对央视行为的控制,这类组件以后再也不会改变了,我们称之为无状态组件(stateless组件),简单地说,就是不会与用户产生交互,或者发送异步请求。
2.什么是有状态组件?
如果组建创建后会根据用户的不同交互产生不同的行为(如更改样式),这一类组件我们称之为有状态,组建处于那种状态是由用户决定。
3.state属性是什么?
组件内部通常会维护一个状态,这个属性就是state,和props一样,我们都可以更改他们,但是我们说props是在组建创建是传递的属性值不同而决定的,因此以后通常是更改不了的(除了子组件)state通常是在产生交互时候改变的,一次她的改变永远伴随着一个交互,每次state,props的改变都会执行一次render方法来重新渲染组件,组件是否更改是由虚拟dom有没有改变决定,如果虚拟dom改变了组件就会渲染。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>组件复用</title> </head> <body> <div id="root1"></div> <div id="root2"></div> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> <script type="text/babel"> var Ul=React.createClass({ setLi:function(){ return this.props.liData.map(function(value,index){ return ( <li key={index}>{value}</li> ) }) }, render:function(){ return ( <ul>{this.setLi()}</ul> ) } }); ReactDOM.render( <Ul liData={[1,2,3]}/>, document.getElementById("root") ); ReactDOM.render( <Ul liData={[1,2,3]}/>, document.getElementById("root1") ); </script> </body> </html>
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>复合组件</title> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> var SuperComponent=React.createClass({ render:function(){ return ( <div> <SupComponent name={this.props.name}/> </div> ) } }); var SupComponent=React.createClass({ render:function(){ return ( <h1>{this.props.name}</h1> ); } }); ReactDOM.render( <SuperComponent name="浮沉"/>, document.getElementById("root") ); </script> </body> </html>
组件的样式
1.样式style属性的值只能是对象,不能为style添加字符串的值
2.Font-size这类要用驼峰式fontSize
3.Css3前缀的属性第一个字母要大写WebkitTransform
4.组件中定义一个虚拟dom我们都要用对象,并且可以使用变量,变量当中可以使用表达式。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>带样式的组件</title> <style> .style{background-color: #000000;} </style> </head> <body> <div id="root"></div> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> <script type="text/babel"> var HelloMessage=React.createClass({ render:function(){ var style={ color:"red" } return ( <div className="style"> <h1 style={style}>Hello,React!</h1> <h1 style={{color:"green"}}>Hello,Angular!</h1> </div> ) } }) ReactDOM.render( <HelloMessage/>, document.getElementById("root") ); </script> </body> </html>
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>带事件的组件</title> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> var LikeButton=React.createClass({ getInitialState:function(){ return {liked:false}; }, handleClick:function(e){ this.setState({liked:!this.state.liked}); }, render:function(){ var text=this.state.liked?"喜欢":"不喜欢"; return ( <p onClick={this.handleClick}> 我{text}react! </p> ); } }); ReactDOM.render( <LikeButton/>, document.getElementById("root") ); </script> </body> </html>
React组件生命周期
组建的生命周期可分成三个状态:
Mounting:以插入真是DOM
Updating:正在被重新渲染
Unmounting:已移除真实DOM
生命周期的方法有:
componentWillMount:在渲染前调用,在客户端也在服务端
componentDidMount:在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。如果你想和其他javascript框架一起使用,可以在这个方法中调用setTImeout,setInterval或者发送Ajax请求等操作(防止异步操作阻塞UI)。
ComponentWIllReceiveProps在组建接收到一个props时被调用。这个方法在初始化render时不会被调用。
shouldComponentUpdate返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用
componentDIdupdate: 在组件完成更新后立即调用。在初始化时不会被调用。
componentWillUnmount:在组件从DOM中移出的时候激励被调用。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>生命周期</title> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> var Hello=React.createClass({ getInitialState:function(){ return {opacity:1} }, componentDidMount:function(){ this.timer=setInterval(function(){ var opacity=this.state.opacity; opacity-=.05; if(opacity<0.1) { opacity=1; } this.setState({opacity:opacity}); }.bind(this),100); }, render:function(){ return ( <div style={{opacity:this.state.opacity}}> Hello React! </div> ) } }); ReactDOM.render( <Hello name="world"/>, document.getElementById("root") ); </script> </body> </html>
React Refs
React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。
这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>ref的使用</title> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> var MyComponent = React.createClass({ handleClick: function() { // 使用原生的 DOM API 获取焦点 this.refs.myInput.focus(); }, render: function() { // 当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs return ( <div> <input type="text" ref="myInput" /> <input type="button" value="点我输入框获取焦点" onClick={this.handleClick} /> </div> ); } }); ReactDOM.render( <MyComponent />, document.getElementById('root') ); </script> </body> </html>