一.引出生命周期
1.组件生命周期
以下代码实现功能:
页面渲染出来,文字自动更改透明度至完全透明,不断重复,在点击按钮后,组件消失,生命周期结束
componentDidMount()// 组价挂载完毕调用,只调一次
// 组件将要卸载
componentWillUnmount()
// render调用的时机:初始化渲染,状态更新之后
render()
<!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>Document</title>
</head>
<body>
<div id= 'test'></div>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<!-- 引入prop-types,用于对标签属性进行限制 -->
<!-- <script type="text/javascript" src="..js/prop-types.js"></script> -->
<script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.js"></script>
<script type="text/babel">
// 挂载mount,卸载unmount
// 生命周期回调函数=生命周期钩子函数=生命周期函数=生命周期钩子
class Life extends React.Component {
state={opacity:1}
death = ()=>{
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
// 组价挂载完毕调用,只调一次
componentDidMount(){
this.timer = setInterval(()=>{
// 获取原状态
let {opacity} = this.state
// 改变
opacity -=0.1
if(opacity<=0) opacity = 1
// 设置新的透明度
this.setState({opacity})
},200)
}
// 组件将要卸载
componentWillUnmount(){
// 清除定时器
clearInterval(this.timer)
}
// render调用的时机:初始化渲染,状态更新之后
render(){
return (
<div>
<h2 style={{opacity:this.state.opacity}}>React学不会怎么办</h2>
<button onClick={this.death}>不活了</button>
</div>
)
}
}
// 渲染
ReactDOM.render(<Life/>,document.getElementById('test'))
</script>
</body>
</html>
2.react生命周期(旧):
流程图(旧)
(1)组件挂载时钩子
constructor:构造器,最先调用
componentWillMount:组件将要挂载时调用
render:组件初始化渲染,或状态更新时
componentDidMount:组件挂载完毕时调用
<!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>Document</title>
</head>
<body>
<div id= 'test'></div>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<!-- 引入prop-types,用于对标签属性进行限制 -->
<!-- <script type="text/javascript" src="..js/prop-types.js"></script> -->
<script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.js"></script>
<script type="text/babel">
// 生命周期回调函数=生命周期钩子函数=生命周期函数=生命周期钩子
class Count extends React.Component {
// 1.构造器
constructor(props){
console.log("Count-constructor")
super(props)
// 初始化状态
this.state ={count:0}
}
// 加1按钮回调
add=()=>{
// 获取原状态
const{count}=this.state
this.setState({count:count+1})
}
// 2.组件将要挂载的钩子
componentWillMount(){
console.log("Count-componentWillMount")
}
// 4.组件挂载完毕的钩子
componentDidMount(){
console.log("Count-componentDidMount")
}
//3. render调用的时机:初始化渲染,状态更新之后
render(){
console.log("Count-render")
const {count}=this.state
return (
<div>
<h2 >当前求和为:{count}</h2>
<button onClick={this.add}>点我加一</button>
</div>
)
}
}
ReactDOM.render(<Count/>,document.getElementById('test'))
</script>
</body>
</html>
结果:
(2)组件更新时钩子及卸载组件
正常更新时钩子
卸载组件:ComponentwillUnmount
组件是否应该更新:shouldComponentUpdate(返回值为true时更新)
组件将要更新:componentWillUpdate
组件更新完毕:componentDidUpdate
<!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>Document</title>
</head>
<body>
<div id= 'test'></div>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<!-- 引入prop-types,用于对标签属性进行限制 -->
<!-- <script type="text/javascript" src="..js/prop-types.js"></script> -->
<script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.js"></script>
<script type="text/babel">
// 生命周期回调函数=生命周期钩子函数=生命周期函数=生命周期钩子
class Count extends React.Component {
// 1.1构造器
constructor(props){
console.log("Count-constructor")
super(props)
// 初始化状态
this.state ={count:0}
}
// 加1按钮回调
add=()=>{
// 获取原状态
const{count}=this.state
this.setState({count:count+1})
}
// 卸载组件
death=()=>{
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
// 1.2组件将要挂载的钩子
componentWillMount(){
console.log("Count-componentWillMount")
}
// 1.4组件挂载完毕的钩子
componentDidMount(){
console.log("Count-componentDidMount")
}
// 1.5组件将要卸载的钩子
componentWillUnmount(){
console.log("Count-componentWillUnmount")
}
// 2.1控制组件更新的阀门,默认返回值为真,返回值为真时可以更新,为假时状态不可以更新
shouldComponentUpdate(){
console.log("Count-shouldComponentUpdate")
return true
}
// 2.2组件将要更新钩子
componentWillUpdate(){
console.log("Count-componentWillUpdate")
}
// 2.3组件更新完毕的钩子
componentDidUpdate(){
console.log("Count-componentDidUpdate")
}
//1.3 render调用的时机:初始化渲染,状态更新之后
render(){
console.log("Count-render")
const {count}=this.state
return (
<div>
<h2 >当前求和为:{count}</h2>
<button onClick={this.add}>点我加一</button>
<button onClick={this.death}>卸载组件</button>
</div>
)
}
}
ReactDOM.render(<Count/>,document.getElementById('test'))
</script>
</body>
</html>
结果:点击卸载组件:
更新组件
强制更新时钩子
shouldComponentUpdate返回值为false时也可以更新
<!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>Document</title>
</head>
<body>
<div id= 'test'></div>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<!-- 引入prop-types,用于对标签属性进行限制 -->
<!-- <script type="text/javascript" src="..js/prop-types.js"></script> -->
<script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.js"></script>
<script type="text/babel">
// 生命周期回调函数=生命周期钩子函数=生命周期函数=生命周期钩子
class Count extends React.Component {
// 1.1构造器
constructor(props){
console.log("Count-constructor")
super(props)
// 初始化状态
this.state ={count:0}
}
// 加1按钮回调
add=()=>{
// 获取原状态
const{count}=this.state
this.setState({count:count+1})
}
// 卸载组件
death=()=>{
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
// 强制更新
force=()=>{
this.forceUpdate()
}
// 1.2组件将要挂载的钩子
componentWillMount(){
console.log("Count-componentWillMount")
}
// 1.4组件挂载完毕的钩子
componentDidMount(){
console.log("Count-componentDidMount")
}
// 1.5组件将要卸载的钩子
componentWillUnmount(){
console.log("Count-componentWillUnmount")
}
// 2.1控制组件更新的阀门,默认返回值为真,返回值为真时可以更新,为假时状态不可以更新
shouldComponentUpdate(){
console.log("Count-shouldComponentUpdate")
return false
}
// 2.2组件将要更新钩子
componentWillUpdate(){
console.log("Count-componentWillUpdate")
}
// 2.3组件更新完毕的钩子
componentDidUpdate(){
console.log("Count-componentDidUpdate")
}
//1.3 render调用的时机:初始化渲染,状态更新之后
render(){
console.log("Count-render")
const {count}=this.state
return (
<div>
<h2 >当前求和为:{count}</h2>
<button onClick={this.add}>点我加一</button>
<button onClick={this.death}>卸载组件</button>
<button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
</div>
)
}
}
ReactDOM.render(<Count/>,document.getElementById('test'))
</script>
</body>
</html>
结果:
(3)父组件更新
// 组件将要接收新的props的钩子,第一次调用props不算
componentWillReceiveProps(props){
console.log('B-componentWillReceiveProps',props)
完整代码:
<!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>Document</title>
</head>
<body>
<div id= 'test'></div>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<!-- 引入prop-types,用于对标签属性进行限制 -->
<!-- <script type="text/javascript" src="..js/prop-types.js"></script> -->
<script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.js"></script>
<script type="text/babel">
// 生命周期回调函数=生命周期钩子函数=生命周期函数=生命周期钩子
class Count extends React.Component {
// 1.1构造器
constructor(props){
console.log("Count-constructor")
super(props)
// 初始化状态
this.state ={count:0}
}
// 加1按钮回调
add=()=>{
// 获取原状态
const{count}=this.state
this.setState({count:count+1})
}
// 卸载组件
death=()=>{
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
// 强制更新
force=()=>{
this.forceUpdate()
}
// 1.2组件将要挂载的钩子
componentWillMount(){
console.log("Count-componentWillMount")
}
// 1.4组件挂载完毕的钩子
componentDidMount(){
console.log("Count-componentDidMount")
}
// 1.5组件将要卸载的钩子
componentWillUnmount(){
console.log("Count-componentWillUnmount")
}
// 2.1控制组件更新的阀门,默认返回值为真,返回值为真时可以更新,为假时状态不可以更新
shouldComponentUpdate(){
console.log("Count-shouldComponentUpdate")
return false
}
// 2.2组件将要更新钩子
componentWillUpdate(){
console.log("Count-componentWillUpdate")
}
// 2.3组件更新完毕的钩子
componentDidUpdate(){
console.log("Count-componentDidUpdate")
}
//1.3 render调用的时机:初始化渲染,状态更新之后
render(){
console.log("Count-render")
const {count}=this.state
return (
<div>
<h2 >当前求和为:{count}</h2>
<button onClick={this.add}>点我加一</button>
<button onClick={this.death}>卸载组件</button>
<button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
</div>
)
}
}
// 父组件
class A extends React.Component {
state = {carName:'奔驰'}
changeCar=() => {
this.setState({carName:'奥拓'})
}
render() {
return(
<div>
<div>我是A组件</div>
<button onClick={this.changeCar}>换车</button>
<B carName={this.state.carName}/>
</div>
)
}
}
class B extends React.Component {
// 组件将要接收新的props的钩子,第一次调用props不算
componentWillReceiveProps(props){
console.log('B-componentWillReceiveProps',props)
}
// 组件是否更新的钩子
shouldComponentUpdate(){
console.log('B-shouldComponentUpdate')
return true
}
// 组件将要更新的钩子
componentWillUpdate(){
console.log("B-componentWillUpdate")
}
// 组件更新完毕的钩子
componentDidUpdate(){
console.log("B-componentDidUpdate")
}
render() {
console.log("B-render")
return(
<div>我是B组件,接收到的车是:{this.props.carName}</div>
)
}
}
// 渲染组件
ReactDOM.render(<A/>,document.getElementById('test'))
</script>
</body>
</html>
结果:点击换车按钮后
3.总结生命周期(旧)
生命周期的三个阶段(I日)
1.初始化阶段: 由 ReactDOM.render()触发—初次渲染
- constructor()
- componentWillMount()
- render()(必须使用)
- componentDidMount()(常用,一般在这个钩子中做一些初始化的事,例如:开启定时器,发送网络请求,订阅消息)
2.更新阶段: 由组件内部 this.setSate()或父组件重新 render 触发
- shouldComponentUpdate()
- componentWillUpdate()
- render()
- componentDidUpdate()
- 强制更新少1.
3.卸载组件:由 ReactDOM.unmountComponentAtNode()触发
- componentWillUnmount()(常用,一般做一些收尾的事,例如:关闭定时器,取消订阅消息)