React学习之高级组件巴巴(二十三)

来源:互联网 发布:python安装matplotlib 编辑:程序博客网 时间:2024/05/15 12:30

套路语句

组件是React提供给广大开发者的福利,一可重用,二可装逼,三可事件,简直逆天

1.概述

·React.Component·是一个抽象基类,因为是抽象类所以如果直接使用·React.Component·并没有什么卵用,所以,我们需要继承它,也可以说是让子类的原型指向它,产生子类,同时这个子类要包含至少render这个方法

最简单的例子

class Greeting extends React.Component {  render() {    return <h1>Hello, {this.props.name}</h1>;  }}

当然用React.createClass()也是可以的,它默认继承React.Component

2.组件的生命周期

生命周期即产生到消亡这个阶段会发生的事情。

React中每一个组件都有若干个生命周期这一阶段中会执行的函数,这些函数会用来在某个时刻被React调用执行。

你可以重写这些方法,但是方法的执行时间依旧是React去控制,通过看函数的名称就可以知道这个函数大概发生在什么时候,如果函数名中有will,表示在某些事件发生之前执行,如果函数名中有did则表示在某些事件发生之后才执行

装载

下面这些方法是在一个组件被实例化然后插入到DOM中去时被React执行

constructor()componentWillMount()render()componentDidMount()

更新

当我们改变了props或者state时就会触发更新,然后下面这些函数就是当更新去重新渲染视图时被React执行

componentWillReceiveProps()shouldComponentUpdate()componentWillUpdate()render()componentDidUpdate()

卸载

当一个组件从DOM移除下来后就会调用下面这个函数

componentWillUnmount()

3.其他彪的情况

API

setState()forceUpdate()

上面这两个玩意大家都熟悉不多说

类属性

defaultPropsdisplayNamepropTypes

对象实例的属性

propsstate

上面这些东西将在下面全都详细讲到


4.组件实例化涉及

render()

对于render熟悉到可以占满你的脸,这是组件中必须的函数,否则,嘿嘿,你跟没有创建组件一样。

render被调用,它会检查this.propsthis.state然后返回一个React元素,这个React元素可以是DOM组件,也可以是自定义组件

当然你也可以直接返回nullfalse表示你不想渲染任何事务,这会导致ReactDOM.findDOMNode(this)返回null,这个函数后续会讲到

render被要求必须是一个纯函数,也就是说它不能修改组件的状态,它的功能只是返回需要渲染到视图中的数据,在没有改变状态或者数据之前,这个函数调用都只会产生一个结果,不和浏览器直接进行交互,如果你想进行交互可以用componentDidMount()或者其他的生命周期函数来代替,总的来说,让render的功能更加简单明了是最好的。

提醒

如果shouldComponentUpdate()返回了false这个函数就不会调用

constructor()

这个构造函数在一个组件被装载之前调用,当子类继承了React.Component实现了constrcutor时,应该在所有操作之前调用super(props),否则this.props将不会被定义从而导致BUF不断,因为一些属性是在React.Component中的构造函数创建的,所以一定要最先调用。

同时,constructor是初始化this.state以及一些函数的绑定的绝佳之地,因为它在所有函数事件之前被调用,可想而知,初始化数据应该就在这里面,如果你不需要初始化this.state和绑定一些函数方法,你就可以不需要实现constructor

constructor(props) {  super(props);  this.state = {    color: props.initialColor  };}  

上面这种直接赋值的模式要小心,由于this.setState是异步的,所以建议使用回调函数来同步处理,也许你可能会使用componentWillReceiveProps(nextProps)来同步State的状态,但是很明显回调函数更加简单,且不易出错。

componentWillMount()

在装载之前调用,也在render前面调用,这里要注意的是,此函数只会在组件装载时执行一次,而更新不会执行。这是唯一一个在服务器端挂载时会调用的函数,建议用constructor来代替处理。

componentDidMount()

这个函数在一个组件被挂载之后调用,这个地方一般用来初始化DOM,即将组件挂载到DOM中后,如果需要对DOM进行初始化的话,可以在此函数中处理,如果你要从远程服务器中获取数据的话,可以在这个函数中处理。

当状态改变时,在render之后又会重新调用这个函数。

componentWillReceiveProps()

componentWillReceiveProps(nextProps)

这个函数将在一个被装载完成后的组件接受一个新的props之前被调用,如果你想因为props的改变更新State,这里也许会有点疑惑什么叫做props的改变,props不是相当于个常量吗,不会改变,会的,当这个组件的父组件发生改变时就会影响当前的props,同时componentWillReceiveProps响应也就调用了,然后我们通过比较this.propsnextProps,来判断怎么调用this.setState来更新state的状态[这里需要注意的是父组件的改变不一定引起子组件状态的改变也有可能只是属性的改变,这一点要记住]

针对componentWillReceiveProps函数注意事项

React调用该函数时,props不一定发生了变化,即this.props==nextProps,所以如果你只想处理props改变了的情况,请注意判断,这样一定程度上可以提升性能,因为减少了渲染,当父组件发生变化时,减少重新渲染。

在组件挂载时初始化props是不会调用这个函数的,只有在更新的时候调用,同时 this.setState只影响着this.state,一般不会影响属性而调用这个函数。

.

shouldComponentUpdate()

shouldComponentUpdate(nextProps, nextState)

这个函数之前有一篇博客大篇幅的讲述了是个什么鬼,这里稍微提一下。

在每次state改变时,这个函数都会默认调用,并且在render函数调用前,当然初始化和调用forceUpdate的时候是不会被调用的。

返回false虽然能够阻止当前组件的更新,但是不能够阻止当前组件内部的子组件的执行

当我们的shouldComponentUpdate返回false,接下来的 componentWillUpdate(), render(),和 componentDidUpdate()这几个函数都不会调用,这个函数之后可能会发生一定程度的变化,所以大家要多关注关注

这个函数在继承React.PureComponent后基本就不用管了。

componentWillUpdate()

componentWillUpdate(nextProps, nextState)

但接受到新的props或者新的state时,还没有调用render之前会调用这个函数。
这个函数经常用在更新发生之前做一些准备工作,当然初始化渲染时是不会调用这个方法的,跟shouldComponentUpdate一样。

需要注意的是,这里你不可以调用this.setState(),如果你要通过props来更新状态,请使用componentWillReceiveProps来代替,因为前者会造成死循环。

shouldComponentUpdate() 返回false时这个函数就不会被调用。

componentDidUpdate()

componentDidUpdate(prevProps, prevState)

这个函数将在更新完成之后调用,不会再初始化时调用

当我们的DOM更新后,我们可以在这个函数里面做些什么,比如说处理更新后的DOM,又或者是发出网络请求,等等。

componentWillUnmount()

在组件被卸载和 摧毁之前调用,在这里我们可以做的事情就是清除一些东西和释放资源

setState()

setState(nextState, callback)

更新state状态,通过这个方法可以出发组件更新

对于第一个参数下面两种用法:

对象

this.setState({mykey: 'my new value'});

函数

this.setState((prevState, props) => {  return {myInteger: prevState.myInteger + props.step};});

至于第二个参数回调函数的使用,是在执行更新操作之后才执行这个回调函数,一般这种工作都会在componentDidUpdate中就已经做完了。

setState是异步的,所以没有立即执行,但是会创建一个状态转换动作,而在这个动作做完之前,this.state可能会返回之前的值。

使用setState会引发重新渲染,除非shouldComponentUpdate返回了false,如果组件内部存在一个多变的对象在不断在变化,那么在shouldComponentUpdate中的有条件的渲染操作将不会被执行也就是shouldComponentUpdate不会被执行,只有当setState()被调用时,才会调用shouldComponentUpdate,这就减少了渲染次数,提高了性能。

forceUpdate()

component.forceUpdate(callback)

默认情况下,当你的组件state或者props改变时会重新渲染,如果你想通过其他数据进行渲染,就需要调用forceUpdate()强行进行渲染了。

当调用forceUpdate()时,会导致跳过shouldComponentUpdate函数,然后更新数据,当然这里还是只会更新该更新的。

正常情况下,你应该尽量避免使用forceUpdate(),只用this.propsthis.state来进行更新渲染。

5.类属性

defaultProps

defaultProps是用来给组件类设置默认的props

class CustomButton extends React.Component {  // ...}CustomButton.defaultProps = {  color: 'blue'};

displayName

这个就是类名,在React.createClass中也有设置。

propTypes

套路,就是用来类型检测

6.实例的属性

props

this.props包含着实例化组件被定义的一些数据,当然,里面有一个非常特殊的存在,就是this.props.children

state

由于state会反复变化,所以它应该是一个简单地对象,你不应该在render对它进行设置,否则会出问题。

下一篇将讲ReactReactDOM

1 0
原创粉丝点击