本文主要是针对React的一些demo教程。参考了菜鸟教程中的react教程,作了一些总结。Demo的下载连接是javascript
https://github.com/RealAndMe/react-demo
下面要讲解的例子都在对应的demo中。html
从github下载react-demo须要用到的命令行:java
#下载代码 $ git clone git@github.com:RealAndMe/react-demo.git #安装开发所依赖的模块 $ npm install #运行并监听 $ gulp watch #具体的能够查看以前的相关博客
build文件夹里是须要用到的js库文档react
每个demo文件夹都有
.html和.js
两个文档,其中js文档中放的是主要的JSX功能,html是渲染的jquery
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="contain"></div> <script type="text/babel" src="index.js"></script> </body> </html>
用到的React必须的库:git
注意:React使用独有的JSX,与javascript不兼容,因此凡是使用JSX的地方,都要加上
<script type="text/babel"></script>
github
这里.js
后缀的文档里存放的是React的JSX语法,它是用来代替常规的javascript,执行速度更快。ajax
ReactDOM.render(<div>hello,world!</div>,document.getElementById("contain"));
ReactDOM.render()
方法是将JSX转换为HTML方法,并将其呈现到指定的DOM节点中,是React的基本语法。算法
JSX基本语法规则:遇到HTML标签(以 < 开头),就用HTML规则解析;遇到代码块(以 { 开头),就用JavaScript规则解析。数据库
上面代码是将<div>
块插入到contain
的节点中(查看demo01)
React.createClass()
方法生成一个React组件类,类名首字母必须大写。(查看demo02)
每一个组件都有一个render : function(){}
的函数,用来输出组件,而且函数里都有return返回值。return里描述的就是HTML树结构,只能包含一个顶层标签。。
<Demo02 />
实例化组件类并输出信息。
var Demo02 = React.createClass({ render : function(){ return( <div className="demo02">hello,world!</div> ) } }); ReactDOM.render(<Demo02 />,document.getElementById("contain"));
能够给标签添加样式,在html中添加类是class,可是在JSX中是calssName,而for属性要写成htmlFor,这是由于for和class是javascript的保留字。
在JSX中使用javascript的数组,样式。(查看demo03)
咱们能够添加内联样式。React会在指定元素数字后面自动添加px。
javascript代码块都要用花括号{ }
,注释也须要写在花括号中。
var array = ["lilei","wangdong","yulun"]; /*定义样式*/ var myStyle = { fontSize: 100, color: "red", textAlign: "center" }; var Demo03 = React.createClass({ render : function(){ return( <div style={myStyle}> {/*遍历数组*/} { array.map(function(msg,index){ return <div key={index}>hello,{msg}</div> }) } </div> ) } }); ReactDOM.render(<Demo03 />,document.getElementById("contain"));
数组遍历的时候会有警告提示表示要加上一个key属性,这个key是用来保证react-vdom标识的惟一性。
组件将具备属性,可使用this.props.[attribute]
来访问,attribute是对应的属性的名称。
(查看demo04)
var Demo04 = React.createClass({ render : function(){ return( <div>hello,{this.props.name}</div> ) } }); ReactDOM.render(<Demo04 name="wjy" />,document.getElementById("contain"));
上述代码中就是经过this.props.name
获取组件上的name属性。
this.props.childre属性表示组件的全部子节点。(查看demo05)
React.children.map(this.props.children,function(){})
方法用来遍历子节点的。
var Demo05 = React.createClass({ render : function(){ return( <ol> { React.Children.map(this.props.children,function(msg){ return <li>{msg}</li> }) } </ol> ) } }); ReactDOM.render( <Demo05> <span>你好</span> <span>hello,world</span> </Demo05>, document.getElementById("contain") );
上述代码中,组件<Demo05 />
中有两个子节点,能够经过this.props.children
来读取。
this.props.children
的值有三种状况:
因此要当心处理this.props.children属性。
组件的属性有不少种类型,好比:数值、字符串等,能够经过React.propTypes来验证props是否有效。当传入的是无效的数据时,控制台会抛出一个异常。(查看demo06)
//var flag = "字符串类型"; var flag = 123; var Demo06 = React.createClass({ propTypes : { title : React.PropTypes.string.isRequired }, render : function(){ return( <h1>{this.props.title}</h1> ) } }); ReactDOM.render(<Demo06 title={flag}/>,document.getElementById("contain"));
上述代码中,组件<Demo06 />
有一个title
属性,PropType
告诉React,title属性是必须的,而且数据类型是字符串型。这里咱们给title设置一个数值,这个时候属性验证不经过,控制台会有一个异常信息。
getDefaultProps()方法是为props设置默认值。(查看demo07)
var Demo07 = React.createClass({ getDefaultProps : function() { return{ title : "wangyu" } }, render : function(){ return( <h1>hello,{this.props.title}</h1> ) } }); ReactDOM.render(<Demo07 />,document.getElementById("contain"));
虚拟DOM:组件并非真实的 DOM 节点,而是存在于内存之中的一种数据结构。
只有在虚拟DOM插入到文档以后,才会变成真实DOM。
DOM diff算法:根据 React 的设计,全部的 DOM 变更,都先在虚拟 DOM 上发生,而后再将实际发生变更的部分,反映在真实 DOM上。这样提升了网页的性能表现。
从组件中获取真实的DOM节点,使用ref
属性。(查看demo08)
var Demo08 = React.createClass({ handleClick : function(){ /*用原生的方法focus()获取文本框焦点*/ this.refs.textInput.focus(); }, render : function(){ // 当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs,这是在真实的Dom上进行的 return( <div> <input type="text" ref="textInput"/> <br/> <br/> <input type="button" value="点击获取焦点" onClick={this.handleClick}/> </div> ) } }); ReactDOM.render(<Demo08 / >, document.getElementById("contain"));
上述代码中,<Dome08 />
组件有一个文本输入框的子节点,用来获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了作到这一点,文本输入框必须有一个 ref
属性,而后 this.refs.[refName]
就会返回这个真实的 DOM 节点。
注意:由
于 this.refs.[refName]
属性获取的是真实 DOM ,因此必须等到虚拟 DOM 插入文档之后,才能使用这个属性,不然会报错。
上面代码中,经过为组件指定 Click
事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件以后,才会读取 this.refs.[refName]
属性。
React将组件当作是一个状态机,一开始有一个初始状态,而后用户互动,致使状态变化,从而触发从新渲染 UI (查看demo09)
var Demo09 = React.createClass({ getInitialState: function(){ return {like: false}; }, handleClick: function(){ this.setState({like:!this.state.like}); }, render: function() { var text = this.state.like?"喜欢":"不喜欢"; return ( <div> <p>我{text}你</p> <input value = "点击切换状态" type = "button" onClick = {this.handleClick}/> </div> ); } }); ReactDOM.render(<Demo09 />,document.getElementById("contain"));
上述代码中,getInitialState()
方法定义state初始化的状态,return返回的是一个对象。当用户点击按钮,致使状态改变时,this.setState({})
方法用来修改state状态值,每次修改以后,都会自行调用this.render()
方法,再次渲染组件。
这个对象能够经过this.state.[stateName]
属性来获取,stateName是定义的状态的名称。
this.props
表示那些一旦定义,就再也不改变的特性,而this.state
是会随着用户互动而产生变化的特性。
表单组件中的value属性(好比:<input>,<textarea>,<option>,<select>
)不受任何用户输入的影响,若是要更新或访问该值来响应用户的输入,那么须要用onChange
事件来回调。(查看demo10)
var Demo10 = React.createClass({ getInitialState: function(){ return { value: "你好" }; }, handleChange: function(e){ this.setState({value: e.target.value}); }, render: function(){ var value = this.state.value; return ( <div> <input type="text" value={value} onChange={this.handleChange} /> <p>{value}</p> </div> ); } }); ReactDOM.render(<Demo10 />,document.getElementById("contain"));
上述代码中,文本框输入的值须要用 onChange
事件的回调函数,经过 event.target.value
读取用户输入的值。textarea 元素、select元素、radio元素都属于这种状况
组件的生命周期有三个状态:
Mounting
:已插入真实的DOMUpdating
:正在被从新渲染Unmounting
已移出真实的DOM生命周期的方法总共有7种:
will
函数在进入状态以前调用,did
在进入状态以后调用。
componentWillMount
在渲染以前调用componentDidMount
在第一次渲染以后调用。以后组件已经生成了对应的DOM结构,能够经过this.getDOMNode()来进行访问。 若是你想和其余JavaScript框架一块儿使用,能够在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操做(防止异部操做阻塞UI)。componentWillReceiveProps
组件接收到新的prop时调用,在初始化render时不调用。shouldComponentUpdate
组件判断是否须要从新渲染时componentWillUpdate
组件在接收到新的prop或state但尚未渲染时componentDidUpdate
组件完成更新后调用componentWillUnmount
组件在DOM移出后调用var Demo11 = React.createClass({ getDefaultProps: function(){ return {name: "wjy"}; }, getInitialState: function () { return {opacity: 1.0}; }, componentDidMount: function () { setInterval(function () { var opacity = this.state.opacity; opacity -= .05; if (opacity < 0.1) { opacity = 1.0; } this.setState({ opacity: opacity }); }.bind(this), 100); }, render: function () { return ( <div style={{opacity: this.state.opacity}}> Hello {this.props.name} </div> ); } }); ReactDOM.render(<Demo11 />,document.getElementById("contain"));
在组件<Demo11 />
加载完以后,经过该componentDidMount
方法设置setInterval(function(){},time)
定时器,每100ms从新设置组件透明度,而后从新渲染。(查看demo11)
其中给函数加上
bind(this)
是为了给当前的对象绑定事件,防止出错
组件的样式要注意,React 组件样式是一个对象,因此第一重大括号表示这是 JavaScript 语法,第二重大括号表示样式对象
style={{opacity: this.state.opacity}} //正确写法
React 组件的数据能够经过 componentDidMount
方法中的 Ajax 来获取,当从服务端获取数据库能够将数据存储在 state 中,再用 this.setState
方法从新渲染 UI。(查看demo12)
var Demo12 = React.createClass({ getInitialState: function() { return { username: '', lastGistUrl: '' }; }, componentDidMount: function() { /* *jquery ajax——get()方法经过远程HTTP GET请求载入信息,取代复杂$.ajax $.get(this.props.source,function(data){ var lastGist = data[0]; if(this.isMounted()){ this.setState({ username: lastGist.owner.login, lastGistUrl: lastGist.html_url }); }; }.bind(this));*/ $.ajax({ url: this.props.source, type: "get", success: function(data){ var lastGist = data[0]; if(this.isMounted()){ this.setState({ username: lastGist.owner.login, lastGistUrl: lastGist.html_url }); }; }.bind(this) }); }, render: function() { return ( <div> {this.state.username}用户最新的共享地址: <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a> </div> ); } }); ReactDOM.render(<Demo12 source="https://api.github.com/users/octocat/gists"/>,document.getElementById("contain"));
$
上述代码中,利用了jQuery的ajax()方法来获取服务器端的数据,也能够经过jquery的ajax的$.get(url,data,sucess(),dataType)
方法经过远程HTTP GET请求载入信息,取代复杂$.ajax。
注意:在函数中常常会用到
bind(this)
,这里的this指向就是componentDidMount()
中的this也就是这个react对象,这样才可以正确访问react属性方法this.state,this.setState
等
JSX 容许直接在模板插入 JavaScript 变量。若是这个变量是一个数组,则会展开这个数组的全部成员。查看demo13)
var Demo13 = React.createClass({ render: function() { var array = [ <h1>你好!</h1>, <h2>hello,world!</h2> ]; return ( <div>{array}</div> ); } }); ReactDOM.render(<Demo13 />,document.getElementById("contain"));
上面代码的array变量是一个数组,结果 JSX 会把它的全部成员,添加到模板中。
有道云笔记参考:http://note.youdao.com/noteshare?id=93e15b78b01eca521abc083659c7f356&sub=4CA29FC7AE614755889C60A513DDAF44