react-native的组件生命周期
组件的相关方法
render
每个组件必须提供render方法。说该函数不修改组件的 state,你也可以返回 null 或者 false 来表明不需要渲染任何东西
- 不要在render()函数中做复杂的操作,更不要进行网络请求,数据库读写,I/O等操作。
getInitialState
初始化组件状态,在组件挂载之前调用一次。返回值将会作为 this.state的初始值。
getDefaultProps
该方法在任何实例创建之前调用,因此不能依赖于 this.props。另外,getDefaultProps() 返回的任何复杂对象将会在实例间共享,而不是每个实例拥有一份拷贝。
PropTypes
propTypes 对象用于验证传入到组件的 props,为类型检查
statics
statics 对象允许你定义静态的方法,这些静态的方法可以在组件类上调用
var MyComponent = React.createClass({
statics: {
customMethod: function(foo) {
return foo === 'bar';
}
},
render: function() {
}
});
MyComponent.customMethod('bar'); // true
在这个块儿里面定义的方法都是静态的,你可以通过ClassName.funcationName的形式调用它。
这些方法不能获取组件的 props 和 state。如果你想在静态方法中检查 props 的值,在调用处把 props 作为参数传入到静态方法。
isMounted
boolean isMounted(),当组件被渲染到DOM,该方法返回true,否则返回false。该方法通常用于异步任务完成后修改state前的检查,以避免修改一个没有被渲染的组件的state。
但是不推荐这种方式,等下讲完周期后我们再来看这个问题
当componentDidMount被调用时该变量为true,当 componentWillUnmount被调用时,该变量为false,这样该变量就可以当isMounted()来使用。但还不够,到目前为止,我们只是通过变量来替代isMounted(),还没有做任何的优化,接下来我们需要在componentWillUnmount被调用时取消所有的异步回调,主动释放所有资源,这样就能避免被卸载的组件还持有资源的引用的情况,从而减少了内存溢出等情况的发生。
组件的生命周期
分成三个状态:
- Mounting:已插入真实 DOM
- Updating:正在被重新渲染
- Unmounting:已移出真实 DOM
[站外图片上传中...(image-e2f3a-1522160563385)]
componentWillMount
初始化了状态之后,在第一次绘制 render() 之前
componentDidMount
组件第一次绘制之后,会调用 componentDidMount(),通知组件已经加载完成
这个函数调用的时候,其虚拟 DOM 已经构建完成,你可以在这个函数开始获取其中的元素或者子组件了
componentWillReceiveProps
如果组件收到新的属性(props),就会调用 componentWillReceiveProps()
void componentWillReceiveProps(
object nextProps
)
输入参数 nextProps 是即将被设置的属性,旧的属性还是可以通过 this.props 来获取。在这个回调函数里面,你可以根据属性的变化,通过调用 this.setState() 来更新你的组件状态,这里调用更新状态是安全的,并不会触发额外的 render() 调用
shouldComponentUpdate
当组件接收到新的属性和状态改变的话,都会触发调用 shouldComponentUpdate
boolean shouldComponentUpdate(
object nextProps, object nextState
)
输入参数 nextProps 和上面的 componentWillReceiveProps 函数一样,nextState 表示组件即将更新的状态值。这个函数的返回值决定是否需要更新组件,如果 true 表示需要更新,继续走后面的更新流程。否者,则不更新,直接进入等待状态。通过检查变化前后属性和状态,来决定 UI 是否需要更新,能有效提高应用性能
componentWillUpdate
如果组件状态或者属性改变,并且上面的 shouldComponentUpdate(...) 返回为 true,就会开始准更新组件,并调用 componentWillUpdate()
void componentWillUpdate(
object nextProps, object nextState
)
在这个回调中,可以做一些在更新界面之前要做的事情。需要特别注意的是,在这个函数里面,你就不能使用 this.setState 来修改状态。这个函数调用之后,就会把 nextProps 和 nextState 分别设置到 this.props 和 this.state 中。紧接着这个函数,就会调用 render() 来更新界面了
componentDidUpdate
调用了 render() 更新完成界面之后,会调用 componentDidUpdate() 来得到通知
void componentDidUpdate(
object prevProps, object prevState
)
因为到这里已经完成了属性和状态的更新了,此函数的输入参数变成了 prevProps 和 prevState。
componentWillUnmount
当组件要被从界面上移除的时候,就会调用 componentWillUnmount()。可以做一些组件相关的清理工作,例如取消计时器、网络请求等
生命周期 | 调用次数 | 能否使用 setSate() |
---|---|---|
getDefaultProps | 1 | 否 |
getInitialState | 1 | 否 |
componentWillMount | 1 | 是 |
render | >=1 | 否 |
componentDidMount | 1 | 是 |
componentWillReceiveProps | >=0 | 是 |
shouldComponentUpdate | >=0 | 否 |
componentWillUpdate | >=0 | 否 |
componentDidUpdate | >=0 | 否 |
componentWillUnmount | 1 | 否 |
export default class LifeCycleComponent extends Component {
constructor(props) {
super(props);
console.log(" --- LifeCycleComponent --- 构造函数 ")
this.state={
count:0,
}
}
componentWillMount() {
console.log(" --- LifeCycleComponent --- componentWillMount 只调用一次,在初始化渲染执行之前立刻调用 ")
}
componentDidMount() {
console.log(" --- LifeCycleComponent --- componentDidMount 在初始化渲染执行之后立刻调用一次 ")
}
componentWillReceiveProps(nextProps) {
console.log(" --- LifeCycleComponent --- componentWillReceiveProps 初始化后 在组件接收到新的 props 的时候调用 ")
}
//该方法在初始化渲染的时候不会调用,在使用 forceUpdate 方法的时候也不会。如果确定新的 props 和 state 不会导致组件更新,则此处应该 返回 false
shouldComponentUpdate(nextProps, nextState) {
console.log(" --- LifeCycleComponent --- shouldComponentUpdate 在接收到新的 props 或者 state,将要渲染之前调用 ")
return true;
}
componentWillUpdate(nextProps, nextState) {
console.log(" --- LifeCycleComponent --- componentWillUpdate 在接收到新的 props 或者 state 之前立刻调用 ")
}
componentDidUpdate(prevProps, prevState) {
console.log(" --- LifeCycleComponent --- componentDidUpdate 在组件的更新已经同步到 DOM 中之后立刻被调用 ")
}
componentWillUnmount() {
console.log(" --- LifeCycleComponent --- componentWillUnmount 在组件从 DOM 中移除的时候立刻被调用")
}
render() {
console.log(" --- LifeCycleComponent --- render")
return <View>
<Text
style={{fontSize:40,backgroundColor:'red'}}
onPress={() => this.dotask()}>
揍你</Text>
<Text style={{fontSize:40,backgroundColor:'yellow'}}>被打了{this.state.count}次</Text>
</View>;
}
dotask(){
this.setState({
count:this.state.count+1,
});
CustomToast.show('揍你'+this.state.count+'次',CustomToast.SHORT);
}
}