持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情
生命周期
- 组件从挂载到卸载他会经历一些特定的阶段
- React组件中包含一系列的钩子函数(生命周期回调函数),会在特定的时刻调用。
- 我们在定义组件的时候,会在特定的生命周期回调函数中做特定的函数
旧版本的React答题分为三个阶段,每个阶段又有不同的生命周期回调函数,如下所示,旧版本指16之前的版本(包含)
1. 初始化阶段:有ReactDOM.render()触发 ------初次渲染component
- 1.constructor() (初始化)
- 2.componentWillMount() (组件将要挂载)
- 3.render() (DOM渲染 ,必须的)
- 4.componentDidMount() (组件已挂载完毕 ,常用)
2.更新阶段:由组件内部this.setState()或者父组件render 触发
- 1.shouldComponentUpdate() (组件更新开关)
- 2.componentWillUpdate() (组件将要更新)
- 3.render() (DOM 更新渲染 ,必须的)
- 4.componentDidUpdate() (组件更新完毕)
3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
- 1.componentWillUnmount() (组件将要卸载,常用) 一般在这个钩子中做一些收尾的事情,例如:关闭定时器,取消订阅消息
旧生命周期代码
当前的版本是React16
过一遍生命周期的代码,增加印象,后面对比一下新的React声明周期
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学习React</title>
</head>
<body>
<div id="test"></div>
<script type="text/javascript" src="./js/react.development.js"></script>
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/babel">
class Login extends React.Component {
state = { opacity: 1 }
remove = () => {
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
//组件挂载完毕
componentDidMount() {
setInterval(() => {
let { opacity } = this.state //获取透明度
opacity -= 0.1
if (opacity <= 0) opacity = 1
this.setState({ opacity })
}, 200)
}
//组件卸载之前
componentWillUnmount() {
clearInterval(this.timer)
}
//初始化渲染,状态更新之后
render() {
console.log('render')
return (
<div>
<h2 style={{ opacity: this.state.opacity }}>我不是云南的怎么办?</h2>
<button onClick={this.remove}>重新投胎</button>
</div>
)
}
}
ReactDOM.render(<Login />, document.getElementById('test'))
</script>
</body>
</html>`
这个代码只简单展示了组件卸载前清除组件的定时器的例子,这种情况非常常见
constructor 这个钩子函数我们之前就用过了就不必再讲了
上面缺失了一个componentWillMount函数,这个钩子函数是组件即将挂载的功能,这里做主要功能就不一一使用这个函数了,下面测试一下父组件render ,只展示javascript 代码
<script type="text/babel">
class A extends React.Component {
state = { province: '云南' }
changeProvince = () => {
this.setState({ province: '广东' })
}
render() {
return (
<div>
<div>我是父组件</div>
<button onClick={this.changeProvince}>换地方</button>
<B province={this.state.province} />
</div>
)
}
}
class B extends React.Component {
componentWillReceiveProps() { //这个第一次传的不算。第二次渲染才会调用
console.log('B componentWillReceiveProps')
}
shouldComponentUpdate() { //组件更新的开关
console.log('B shouldComponentUpdate')
return true //必须return true 不然不会执行下面更新操作
}
componentWillUpdate() { //组件将要更新
console.log('B componentWillUpdate')
}
componentDidUpdate() { //组件更新完毕
console.log('B componentDidMount')
}
render() {
console.log('B Rander')
return (
<div>
我是子组件,接收到的地方是:{this.props.province}
</div>
)
}
}
ReactDOM.render(<A />, document.getElementById('test'))
</script>
效果展示:
代码展示了父组件render钩子函数的顺序,分别为:
- 组件将要接受新的props:componentWillReceiveProps
- 组件更新开关:shouldComponentUpdate
- 组件将要更新:componentWillUpdate
- 组件更新 :render
- 组件更新完毕:componentDidUpdate
总结
React 组件的声明周期的函数的名字都比较长,语义化非常好,经常用就会记住了,今天只做稍微了解,下篇就是对比一下新的组件声明周期。