react组件的生命周期
- 1、什么是生命周期?
- 2、生命周期流程图(旧)
- 3、生命周期流程图(新)
- 3.1、被弃用的三个钩子函数
- 3.2、生命周期的三个阶段(新)
需求:定义组件实现以下功能:
- 让指定的文本做显示 / 隐藏的渐变动画
- 从完全可见,到彻底消失,耗时2S
- 点击“不活了”按钮从界面中卸载组件
//1、创建组件
class Demo extends React.Component {
state = {opacity: 1}
death = () => {
//卸载组件
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
//组件完成挂载后执行
componentDidMount() {
this.timer=setInterval(() => {
// 获取原状态
let {opacity} = this.state;
// 减小0.1
opacity -= 0.1
if (opacity <= 0) opacity = 1
this.setState({opacity})
}, 200)
}
//组件将要卸载时调用
componentWillUnmount(){
//清除定时器
clearInterval(this.timer)
}
//render调用时机:初始化渲染、状态更新之后
render() {
return (
<div>
<h1 style={{opacity: this.state.opacity}}>react感觉还是有点难滴!!!怎么办?</h1>
<button onClick={this.death}>不活了</button>
</div>
)
}
}
//2、渲染虚拟DOM
ReactDOM.render(<Demo/>, document.getElementById('test'))
1、什么是生命周期?
- 组件从创建到死亡它会经历一些特定的阶段。
- React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。
- 我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作
2、生命周期流程图(旧)

2.1 、生命周期的三个阶段(旧)
-
初始化阶段:
由ReactDOM.render()触发—初次渲染
- constructor()
- componentWillMount()
- render()
- componentDidMount()---------常用,一般在这个钩子函数做一些初始化操作,例如:开启定时器,发起网络请求,订阅消息等等…
-
更新阶段
: 由组件内部this.setSate()或父组件重新render触发
- shouldComponentUpdate()
- componentWillUpdate()
- render()--------必须使用的一个
- componentDidUpdate()
-
卸载组件
: 由ReactDOM.unmountComponentAtNode()触发
- componentWillUnmount()--------常用,一般在这个钩子函数做一些收尾的事儿,例如:关闭定时器、取消定时器…
//1、创建组件
class Count extends React.Component {
//构造器
constructor(props) {
console.log('count-constructor');
super(props);
this.state = {count: 0}
}
//将要挂载
componentWillMount() {
console.log('count-componentWillMount');
}
//挂载后
componentDidMount() {
console.log('count-componentDidMount');
}
//将要卸载
componentWillUnmount() {
//清除定时器
console.log('count-componentWillUnmount');
}
//控制组件是否更新的”阀门“
shouldComponentUpdate() {
console.log('count-shouldComponentUpdate');
return true;//返回false状态无法更新,返回值为true,则更新
}
//组件将要更新
componentWillUpdate() {
console.log('count-componentWillUpdate');
}
//组件更新完成
componentDidUpdate() {
console.log('count-componentDidUpdate');
}
//count+1
add = () => {
// 获取原状态
let {count} = this.state;
this.setState({
count: count + 1
})
}
//卸载组件
unmount = () => {
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
//强制更新
force = () => {
//强制更新(无 控制组件是否更新的‘阀门’的步骤)
this.forceUpdate();
}
render() {
console.log('count-render');
let {count} = this.state;
return (
<div>
<h1>当前求和为:{count}</h1>
<button onClick={this.add}>点击+1</button>
<button onClick={this.unmount}>卸载组件</button>
<button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
</div>
)
}
}
//父组件
class Father extends React.Component {
state = {carName: '宝马'}
changeCar = () => {
this.setState({
carName: '马自达'
})
}
render() {
return (<div>
<div>Father</div>
<button onClick={this.changeCar}>换车</button>
<Child carName={this.state.carName}></Child>
</div>
)
}
}
//子组件
class Child extends React.Component {
//组件将要接收父组件传过来的新的属性值(第一次不会执行)
componentWillReceiveProps(props) {
console.log('Child-componentWillReceiveProps',props);
}
render() {
return (<div>我是Child组件,我从Father组件中接收到的车是:{this.props.carName}</div>)
}
}
//2、渲染虚拟DOM
// ReactDOM.render(<Count/>, document.getElementById('test'))
ReactDOM.render(<Father/>, document.getElementById('test'))
3、生命周期流程图(新)

3.1、被弃用的三个钩子函数
-
- componentWillMount
-
- componentWillReceiveProps
-
- componentWillUpdate
现在使用会出现警告,需要加上UNSAFE_
前缀才能使用,以后可能会被彻底废弃,不建议使用。
3.2、生命周期的三个阶段(新)
-
初始化阶段:
由ReactDOM.render()触发—初次渲染
- constructor()
- getDerivedStateFromProps
- render()
- componentDidMount()---------常用,一般在这个钩子函数做一些初始化操作,例如:开启定时器,发起网络请求,订阅消息等等…
-
更新阶段:
由组件内部this.setSate()或父组件重新render触发
- getDerivedStateFromProps
- shouldComponentUpdate()
- render()
- getSnapshotBeforeUpdate
- componentDidUpdate()
-
卸载组件:
由ReactDOM.unmountComponentAtNode()触发
- componentWillUnmount()--------常用,一般在这个钩子函数做一些收尾的事儿,例如:关闭定时器、取消定时器…
//1、创建组件
class Count extends React.Component {
//构造器
constructor(props) {
console.log('count-constructor');
super(props);
this.state = {count: 0}
}
// 若state的值在任何时候都取决于props,可以使用
//派生状态(state的值在任何时候都取决于props.派生状态会导致代码冗余,并使组件难以维护)
static getDerivedStateFromProps(props, state) {
//必须有返回值,null或state obj状态对象
console.log('count-getDerivedStateFromProps', props, state);
return null;
// return props;//返回状态对象会影响状态的更新
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log('count-getSnapshotBeforeUpdate', prevProps, prevState);
return 'xiao';
}
//挂载后
componentDidMount() {
console.log('count-componentDidMount');
}
//将要卸载
componentWillUnmount() {
//清除定时器
console.log('count-componentWillUnmount');
}
//控制组件是否更新的”阀门“
shouldComponentUpdate() {
console.log('count-shouldComponentUpdate');
return true;//返回false状态无法更新,返回值为true,则更新
}
//组件更新完成(第三个参数为getSnapshotBeforeUpdate钩子函数的返回值)
componentDidUpdate(prevProps, prevState,snapshotValue) {
console.log('count-componentDidUpdate',prevProps, prevState,snapshotValue);
}
//count+1
add = () => {
// 获取原状态
let {count} = this.state;
this.setState({
count: count + 1
})
}
//卸载组件
unmount = () => {
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
render() {
console.log('count-render');
let {count} = this.state;
return (
<div>
<h1>当前求和为:{count}</h1>
<button onClick={this.add}>点击+1</button>
<button onClick={this.unmount}>卸载组件</button>
</div>
)
}
}
//2、渲染虚拟DOM
ReactDOM.render(<Count count="99"/>, document.getElementById('test'))
getSnapshotBeforeUpdate的应用场景:
以特殊方式处理滚动位置
//1、创建组件
class NewsList extends React.Component {
state = {newsArr: []}
componentDidMount() {
setInterval(() => {
// 获取原来的状态值
const {newsArr} = this.state;
// 模拟一条新闻
const news = '新闻' + (newsArr.length + 1);
// 更新状态
this.setState({
newsArr: [news, ...newsArr]
})
}, 1000)
}
getSnapshotBeforeUpdate() {
return this.refs.list.scrollHeight
}
componentDidUpdate(prevProps, prevState, snapshotValue) {
this.refs.list.scrollTop += this.refs.list.scrollHeight - snapshotValue;
}
render() {
return (
<div className="list" ref="list">
{this.state.newsArr.map((item, index) => {
return <div className="news" key={index}>{item}</div>
})}
</div>
)
}
}
ReactDOM.render(<NewsList/>, document.getElementById('test'))