也能够在这里看:http://leozdgao.me/liao-jie-ge-reactzu-jian/html
最近React,这个专一View层的库格外火热,我我的已经探索了一段时间,原本一直想写一些文字,总结下React应用开发和webpack构建工具的经验。不过懒癌复发,一直没动笔。前段时间给团队安利这个库,如今要开始用它写项目了,因此本身挖的坑要填上,就开始写一些基本的东西,就先从介绍React组件的基础开始。react
标题叫“一个简单的组件”,因而先来看下官方网站上一个叫作“A Simple Component”的例子来感觉下:webpack
var HelloMessage = React.createClass({ render: function() { return <div>Hello {this.props.name}</div> } }) React.render(<HelloMessage name="John" />, mountNode)
好的,经过React提供的工厂方法,咱们建立了一个组件,在这里,咱们认为createClass
建立了一张blueprint,而经过jsx语法建立的<HelloMessage name="John" />
则返回一个ReactElement
对象来具体地告诉React要如何渲染组件(由于除了blueprint之外还须要一些外部状态的传入),这等同于调用React.createElement(HelloMessage, { name: 'John' }, 'Hello ', this.props.name)
。web
以后,React就能够根据ReactElement
对象,把组件挂载到页面的某个节点上去,也就是React.render
方法在作的事情,这个方法返回一个组件的实例,同时也意味着你能够在已有项目中的一小部分尝试React。api
下面来具体介绍下。浏览器
上面的例子里看着像是把HTML写在了Js里,其实是经过一种更加清晰易读且易维护的语法JSX来建立ReactElement
对象。对React来讲JSX是可选的,若是真的不喜欢也能够用React.createElement
这个api。babel
固然有JSX语法的js文件是不能直接在浏览器中运行的,咱们能够用官方的JSXTransformer
或者是babel
来转换。函数
须要注意的是class
和for
这两个HTML属性,因为组件的属性实际是以对象形式传递的,好比上面的{ name: 'John' }
,另外js不容许关键字做为属性名,因此须要分别用className
和htmlFor
代替。工具
建立组件的时候须要给React.createClass
提供一个对象,这个对象必须包含一个render
方法和若干可选的生命周期方法。性能
要注意的是咱们须要保证render
函数是纯函数,即一样的输入始终返回相同的输出,而且执行过程当中没有反作用(和DOM交互或者发Ajax请求)。但一个组件要和DOM交互或者发Ajax请求需求是很正常的,那么就要用到其余生命周期方法了。
除此以外,更重要的部分是,让一个组件能够工做除了有blueprint外,还须要组件状态。对于一个React组件来讲,分为不可变状态this.props
和可变状态this.states
。
咱们能够经过this.props
决定一个组件内的部分呈现内容,好比上例中咱们但愿呈现的名字是John,且不会改变。然而对于一个DropDownList
而言,仅在点击它时,一个下拉列表才会显示出来,那么咱们认为这个下拉列表是否显示就是一个可变状态。
说到可变状态,那么要这么变?React并不但愿咱们直接修改this.states
,咱们须要使用this.setState
的方式修改状态,由于每次调用this.setState
,render
方法都会被再次调用,同时也会调用一些相关的生命周期函数。this.setState
接受一个对象做为新状态的patch,也就是说这个对象不会覆盖现有的this.states
,而是一个相似extend的行为。
咱们也能够提供一些默认状态:
getDefaultProps () { return { name: 'defaultName' }; }, getInitialState: function() { return { listShowed: false }; },
其中getDefaultProps
仅会被调用一次,这里的意思是不管你会建立多少个ReactElement
,这个函数都只执行一次,以后的默认props
都会直接使用改函数的返回值。
这里须要提一下React提供以ES6的方式建立组件,有意思的是ES6的版本用的是React.Component
,在语意上比createClass
更加明确。getDefaultProps
和getInitialState
在ES6的版本中有些不太同样,相对与getDefaultProps
,ES6将默认属性对象做为了构造函数的一个属性,而getInitialState
则变成了在其构造器函数中给this.state
赋值,来看一个栗子:
class HelloMessage extends React.Component { constructor (props) { this.super(props) this.state = { } // 初始化状态 } render () { return <div>Hello {this.props.name}</div> } } HelloMessage.defaultProps = { name: 'defaultName' }
以前的部分一直有提到生命周期函数,下面就来介绍下:
componentWillMount
会在组件即将被挂载时调用,此时this.refs
对象为空对象。若是在该函数中使用this.setState
,那么会更新this.states
对象,而render
依然只会调用一次,至关因而能够覆盖getInitialState
返回的对象,虽然我以为这没什么意义。
componentDidMount
是很是经常使用的生命周期方法,仅当组件被挂载后调用一次,这意味着能够在这个函数中进行一些DOM操做等,好比但愿组件中的一个textbox能够再挂载后自动获取焦点:
componentDidMount () { const textbox = React.findDOMNode(this.refs.text) if (this.props.autoFocus) textbox.focus() }
componentWillReceiveProps
在将要接受新的props
时被调用,不是说props
是不可变状态吗?状况一般是这样的,当一个父组件包含了一个子组件,子组件的一个props
的值是父组件的states
的值,那么当父组件可变状态改变时,子组件的props
也更新了,因而调用了这个函数。
componentWillReceiveProps (nextProps) { if (this.props.disabled !== nextProps.disabled) { // disabled这个属性改变了 } }
这个生命周期函数componentWillReceiveProps
提供了更新states
的机会,能够调用this.setState
,也是惟一能够在组件更新周期中调用this.setState
的函数。
shouldComponentUpdate
是在更新前根据该函数的返回值决定是否进行此次更新。
shouldComponentUpdate (nextProps, nextState) { // 比较props或者states,返回true则更新照常,返回false则取消更新,且不会调用下面的两个生命周期函数 }
考虑这种状况:父组件有子组件A和子组件B,当父组件调用this.setState
更新一个做为子组件A属性的state
时,render
方法被再次调用,此时组件A和组件B同时被更新,其实真正改变的只有组件A,但组件B也同时被要求更新了,这是没有必要的,因而shouldComponentUpdate
就显的有用了,在该函数体内比较props
或是states
,若是没有改变就取消这个更新,这对性能上算是一个提高。
但若是是复杂对象的比较就比较麻烦了,由于咱们没法经过===
来判断两个对象的键值是否都相等,因而咱们就但愿咱们的对象是不可变的(immutable)。这里再也不展开了,你们能够先自行探索,以后再写这个部分的文字,并介绍immutable.js
componentWillUpdate
在组件被更新前调用一次,能够用来作一些更新前的准备工做,举个栗子:
componentWillUpdate (nextProps, nextState) { if (!this.props.isShowed && nextProps.isShowed) { // 好比下拉菜单此时变的显示了,能够对此监听一些事件什么的 } if (this.props.isShowed && !nextProps.isShowed) { // 好比下拉菜单隐藏了,能够在这里取消事件监听 } }
(组件更新前事情还蛮多的...)
componentDidUpdate
在组件更新完成后调用,能够考虑在这个函数中执行一些DOM操做什么的。
注意:绝对不要在componentWillUpdate
和componentDidUpdate
中调用this.setState
方法,不然将致使无限循环调用。
componentWillUnmount
会在组件即将从挂载点移去时调用,此方法专门用来『擦屁股』,好比去除即将被销毁的DOM节点的引用,或者是清除计时器,取消监听的时间等等。
好了,正文结束,这一篇介绍了React比较基础的部分,但愿对你们有帮助,以后还会有一些更有针对性的部分。如文章中内容有误,还请指正。