学习react教程
网址收藏: react官网,react的github,react的中文文档
1.react是什么?
react起源于facebook的内部项目,因为该公司对市场上所有的javascript mvc框架都不满意,决定自己写一套,用来架设instargm的网站。做完以后,发现很好用,就在2013年5月开源。
2.安装react
- 全局安装react脚手架工具
npm install create-react-app -g
- 安装阮一峰老师的教程
git clone git@github.com:ruanyf/react-demos.git
下载下来
3.react特性
重点:组件,状态
核心: 状态
4.语法。
4.1 html模板
<!doctype html> <html> <head> <!-- 这是核心js --> <script src="../build/react.js"></script> <!-- 这是处理虚拟dom相关的js --> <script src="../build/react-dom.js"></script> <!-- 这是把jsx语法转换为js语法 (注意:jsx就是可以把html写在js里面。) --> <script src="../build/browser.min.js"></script> </head> <body> <div id="example"></div> <!-- 这里加type就是告诉游览器,这里使用的是jsx语法模板。 --> <script type="text/babel"> //这里写 </script> </body> </html>
4.2 reactdom.render()
react最基本的方法,用于把模板转换成html语言,并且插入指定的节点。
例如:
reactdom.render( <h2>welcome to react world!</h2>, document.getelementbyid('myapp') )
4.3 jsx语法
jsx是可以在js中写html,遇到html标签(例如:
<
)就用html
解析,遇到代码块(例如:{
)就用javascript规则解析。
例如:
<!doctype html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="example"></div> <div id="food"></div> <script type="text/babel"> var names = ['alice', 'emily', 'kate']; var foods = ['meal','sala','milk']; reactdom.render( <div> { names.map(function (name, index) { return <div key={index}>hello, {name}!</div> }) } </div>, document.getelementbyid('example') ); reactdom.render( <div> { foods.map(function (food, index) { return <div key={index}>i like eat {food}!</div> }) } </div>, document.getelementbyid('food') ) </script> </body> </html>
4.4 组件 react.createclass()
react允许将代码封装成组件(component),然后把它当成html标签插入到网页中。react.createclass()就是可以创建一个组建类。
例如:
<!doctype html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="foods"></div> <script type="text/babel"> var likefood = react.createclass({ //创建组件类 render: function() { return <p>i like eat <mark>{this.props.name}</mark></p>; } }); reactdom.render( <likefood name="apple"/>, document.getelementbyid('foods') ) </script> </body> </html>
4.5 this.props.children
this.props
对象的属性与组件的属性基本上是一致的,特殊在于this.props.children
属性,它表示组件的所有子节点。
注意: this.props.children
有三个可能,如果当前组件没有子节点,就是显示undefined
;如果有一个子节点,数据类型就是object
;如果有多个子节点,就是array
,所以要小心。
但react提供了一个方法遍历所有子节点,react.children
,通过this.props.children
来遍历。
<!doctype html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="foods"></div> <script type="text/babel"> var foodlist = react.createclass({ render: function() { return ( <ul> { react.children.map(this.props.children,function (child) { return <li>{child}</li>; }) } </ul> ) } }) reactdom.render( <foodlist> <span>hello,</span> <span>i like eat</span> <span>apple!</span> </foodlist>, document.getelementbyid('foods') ) </script> </body> </html>
4.6 proptypes
组件的属性可以接受任何值,如字符串,数字,数组,对象,函数,但是需要一种机制来验证使用组件提供的参数是否符合要求,proptypes就是用来验证这个的。
<!doctype html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="foods"></div> <script type="text/babel"> var str = 123; var mynum = react.createclass({ proptypes: { num: react.proptypes.number.isrequired, }, render: function() { return <h2>{this.props.num}</h2> } }); reactdom.render( <mynum num={str} />, document.getelementbyid('foods') ) </script> </body> </html>
补充:还可以添加默认值。'
getdefaultprops: function() { return { num: 1818 } }
例如:
<!doctype html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="foods"></div> <script type="text/babel"> var str; var mynum = react.createclass({ getdefaultprops: function() { return { num: 1818 } } proptypes: { num: react.proptypes.number.isrequired, }, render: function() { return <h2>{this.props.num}</h2> } }); reactdom.render( <mynum num={str} />, document.getelementbyid('foods') ) </script> </body> </html>
4.7 获取真实的dom节点
组件并不是真的dom节点,只是存在内存中的数据结构,叫做虚拟dom(virtual)。当它插入到文档以后,才会变成真实的dom。
所有的dom变动,先是在虚拟dom上发生变动,然后再在实际发生变动的部分,反映在真实的dom,这种叫做dom diff,它可以极大提高网页的性能表现。
有时需要从组件获取真实的dom的节点,这个时候就要用到ref
属性。
注意:react还支持许多事件,更多请访问。
例如:
<!doctype html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="foods"></div> <script type="text/babel"> var myfoods = react.createclass({ showcontent: function() { this.refs.myfoodinput.focus(); }, render: function() { return ( <div> <input type="text" ref="myfoodinput" /> <input type="button" value="自动聚焦" onclick={this.showcontent} /> </div> ) } }) reactdom.render( <myfoods />, document.getelementbyid('foods') ) </script> </body> </html>
4.8 this.state 状态管理
组件免不了要和用户互动,react的一大创新就是把组件看成是一个状态机,一开始有个初始状态,然后用户互动,导致状态变化,从而重新出发渲染ui。
注意: getinitialstate
方法用于定义初始状态,但同时它是一个对象,这个可以通过this.state
属性读取。
当用户点击组件,导致状态发生变化,this.setstate
方法就会修改状态值,每次修改完,会自动调用this.render
方法,再次渲染组件。
this.props
和this.state
都是描述组件的特性,但是不同的是this.props
是指一旦定义好了,就不再发生变化的特性,而this.state
是会随着用户互动而产生变化的特性。
例如:
<!doctype html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="foods"></div> <script type="text/babel"> var foodbutton = react.createclass({ getinitialstate: function() { return {food: false}; }, callclick: function(event) { this.setstate({food: !this.state.food}); }, render: function() { var text1 = this.state.food ? 'like eat apple' : 'hate eat apple'; return ( <p onclick={this.callclick}> you {text1}! </p> ); } }); reactdom.render( <foodbutton />, document.getelementbyid('foods') ) </script> </body> </html>
4.9 表单
用户在表单填入的内容,属于用户和组件之间的互动,所以不能用
this.state
,而要定义一个onchange
事件的回调函数,通过event.target.value
读取用户的值。
注意:textarea
,select
,radio
都属于这种情况。
例如:
<!doctype html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="food"></div> <script type="text/babel"> var food = react.createclass({ getinitialstate: function() { return {val: 'welcome to react!'}; }, hanchange: function(event) { this.setstate({val:event.target.value}); }, render: function() { var val = this.state.val; return ( <div> <input type="text" value={val} onchange={this.hanchange} /> <p>{val}</p> </div> ); } }) reactdom.render(<food />,document.getelementbyid('food')) </script> </body> </html>
4.10 组件的生命周期
react中组件的生命周期分为三个状态,mounting是已经插入真实dom,updating是正在被重新渲染,unmounting是已移出真实dom。
每个状态都有两种处理函数,will函数是进入状态之前,did函数是进入状态之后,三种状态共计五种函数。
注意:组件的样式style不能写成<div style={opacity: this.state.opacity}>
,要写成<div style={{opacity: this.state.opacity}}>
。
因为react组件样式是个对象,所以第一个大括号表示javascript语法,第二个大括号表示样式对象。
五种函数
componentwillmount()
componentdidmount()
componentwillupdate(object nextprops, object nextstate)
componentwillupdate(object prevstate, object prevstate)
componentwillunmount()
例如:第二种,在已插入真实dom之后触发。
<!doctype html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="food"></div> <script type="text/babel"> var food = react.createclass({ getinitialstate: function() { return { opacity: 0 } }, componentdidmount: function() { this.timer = setinterval(function() { var opacity = this.state.opacity; opacity += .05; if (opacity > 1) { opacity = 0; } this.setstate({ opacity: opacity }) }.bind(this),100); }, render: function() { return ( <div style={{opacity: this.state.opacity}}> hello, {this.props.title} </div> ); } }); reactdom.render( <food title="apple"/>, document.getelementbyid('food') ) </script> </body> </html>
4.11 ajax的使用
组件的数据来源一般都是通过ajax请求从服务器获取,可以使用
componentdidmount()
方法设置ajax请求,等到请求成功,再用this.setstate
方法重新渲染ui。
例如:
<!doctype html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> <script src="../build/jquery.min.js"></script> </head> <body> <div id="food"></div> <script type="text/babel"> var clientgits = react.createclass({ getinitialstate: function() { return { id: '', addr: '' }; }, componentdidmount: function() { $.get(this.props.source,function (result) { var gits = result[0]; this.setstate({ id: gits.id, addr: gits.git_pull_url }); }.bind(this)); }, render: function() { return ( <div> userid is <a href='#userid'>{this.state.id}</a>, git address is <a href={this.state.addr}>{this.state.addr}</a>! </div> ); } }); reactdom.render( <clientgits source="https://api.github.com/users/octocat/gists" />, document.getelementbyid('food') ) </script> </body> </html>
注意:上面采用了jquery的ajax,还可以采用其他的库。我们甚至可以把promise对象传入组件。
例如:
<!doctype html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> <script src="../build/jquery.min.js"></script> </head> <body> <div id="projects"></div> <script type="text/babel"> var projects = react.createclass({ getinitialstate: function() { return { loading: true, error: null, data: null }; }, componentdidmount() { this.props.promise.then( value => this.setstate({loading: false, data: value}), error => this.setstate({loading: false, error: error}) ) }, render: function() { if (this.state.loading) { return <span>loading...</span>; } else if (this.state.error != null) { return <span>error:{this.state.error.message}</span>; } else { var res = this.state.data.items; var reslist = res.map(function (res,index) { return ( <li key={index}><a href={res.html_url} target="_blank">{res.name}</a>({res.stargazers_count} stars)<br/>{res.description}</li> ); }); return ( <main> <h1>github上最受欢迎的js项目</h1> <ul>{reslist}</ul> </main> ); } } }); reactdom.render( <projects promise={$.getjson('https://api.github.com/search/repositories?q=javascript&sort=stars')} />, document.getelementbyid('projects') ) </script> </body> </html>
上一篇: 结婚有风险,单身保平安
下一篇: 关于Python课程的一些思考。