React旧版生命周期
1.组件从创建到死亡它会经历一些特定的阶段
2.React组件中包含一系列的钩子函数(生命周期回调函数),会在特定时刻调用
3.我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作
4.render(),被调用1+n次,1是页面初次渲染,n是页面更新的次数
-
初始化阶段:由ReactDOM.render()触发——初次渲染
- constructor()
- componentWillMount()
- render()
- componentDidMount()
-
更新阶段:由组件内部this.setState()或父组件重新触发render()
- shouldComponentUpdate();
- componentWillUpdate();
- render();
- componentDidUpdate();
-
卸载组件:由ReactDOM.unmountComponentAtNode()触发
+ componentWillUnmount()
最常用的三个钩子是componentDidMount() ,一般用这个钩子,做初始化的事,例如开启定时器,发送网络请求,订阅信息
componentWillUnmount(),一般在这个钩子中做一些收尾的事,例如:关闭定时器,取消订阅信息
render:初始化渲染或更新渲染调用
即将废弃的三个钩子函数:
- componentWillMount 2. componentWillReceiveProps 3. componentWillUpdate
现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。
<!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>
<!-- 引入React核心库 -->
<script src="./js/react.development.js"></script>
<!-- 引入React-dom使用React操作dom -->
<script src="./js/react-dom.development.js"></script>
<!-- 引入babel将jsx转为js -->
<script src="./js/babel.min.js"></script>
<script type="text/babel">
class Count extends React.Component{
constructor(props){
super(props);
console.log('Count_constructor');
};
render(){
console.log('Count_render');
return(
<div>
<h1>React组件生命周期,三个将废弃,增加两个</h1>
<button onClick={this.death}>移除组件</button>
</div>
)
}
death = ()=>{
ReactDOM.unmountComponentAtNode(document.getElementById('test'));
}
// 组件将要挂载时触发的钩子函数
componentWillMount(){
console.log('Count_componentWillMount');
};
// 组件挂载完成触发的钩子函数
componentDidMount(){
console.log('Count_componentDidMount');
}
// 组件将要卸载时触发的钩子函数
componentWillUnmount(){
console.log('Count_componentWillUnmout');
}
}
// 渲染组件
ReactDOM.render(<Count />,document.getElementById('test'));
</script>
</body>
</html>
<!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>
<!-- 引入React核心库 -->
<script src="./js/react.development.js"></script>
<!-- 引入React-dom使用React操作dom -->
<script src="./js/react-dom.development.js"></script>
<!-- 引入babel将jsx转为js -->
<script src="./js/babel.min.js"></script>
<script type="text/babel">
class Count extends React.Component{
constructor(props){
super(props);
console.log('Count_constructor');
};
state = {opacity:1};
render(){
console.log('Count_render');
return(
<div>
<h1 style={{opacity:this.state.opacity}}>React组件生命周期,三个将废弃,增加两个</h1>
<button onClick={this.death}>移除组件</button>
</div>
)
}
death = ()=>{
ReactDOM.unmountComponentAtNode(document.getElementById('test'));
}
// 组件将要挂载时触发的钩子函数
componentWillMount(){
console.log('Count_componentWillMount');
};
// 组件挂载完成触发的钩子函数
componentDidMount(){
console.log('Count_componentDidMount');
this.timer = setInterval(()=>{
let {opacity} = this.state;
opacity -=0.2;
if(opacity<=0){
opacity = 1;
}
this.setState({opacity:opacity});
},200)
}
// 组件将要卸载时触发的钩子函数
componentWillUnmount(){
console.log('Count_componentWillUnmout');
}
}
// 渲染组件
ReactDOM.render(<Count />,document.getElementById('test'));
</script>
</body>
</html>
报错:
不能在组件移除后设置state,防止内存泄漏情况
在组件将要销毁时,要销毁定时器,因为定时器会修改state的值
<!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>
<!-- 引入React核心库 -->
<script src="./js/react.development.js"></script>
<!-- 引入React-dom使用React操作dom -->
<script src="./js/react-dom.development.js"></script>
<!-- 引入babel将jsx转为js -->
<script src="./js/babel.min.js"></script>
<script type="text/babel">
class Count extends React.Component{
constructor(props){
super(props);
console.log('Count_constructor');
};
state = {opacity:1};
render(){
console.log('Count_render');
return(
<div>
<h1 style={{opacity:this.state.opacity}}>React组件生命周期,三个将废弃,增加两个</h1>
<button onClick={this.death}>移除组件</button>
</div>
)
}
death = ()=>{
ReactDOM.unmountComponentAtNode(document.getElementById('test'));
}
// 组件将要挂载时触发的钩子函数
componentWillMount(){
console.log('Count_componentWillMount');
};
// 组件挂载完成触发的钩子函数
componentDidMount(){
console.log('Count_componentDidMount');
this.timer = setInterval(()=>{
let {opacity} = this.state;
opacity -=0.2;
if(opacity<=0){
opacity = 1;
}
this.setState({opacity:opacity});
},200)
}
// 组件将要卸载时触发的钩子函数
componentWillUnmount(){
console.log('Count_componentWillUnmout');
// 清除定时器
clearInterval(this.timer);
}
}
// 渲染组件
ReactDOM.render(<Count />,document.getElementById('test'));
</script>
</body>
</html>
更新后钩子函数的顺序
<!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>
<!-- 引入React核心库 -->
<script src="./js/react.development.js"></script>
<!-- 引入React-dom使用React操作dom -->
<script src="./js/react-dom.development.js"></script>
<!-- 引入babel将jsx转为js -->
<script src="./js/babel.min.js"></script>
<script type="text/babel">
class Count extends React.Component{
constructor(props){
super(props);
console.log('Count_constructor');
};
state = {
count:0
};
render(){
const {count} = this.state;
console.log('Count_render');
return(
<div>
<h2>当前求和:{count}</h2>
<button onClick={this.add}>点我+1</button>
<button onClick={this.death}>卸载组件</button>
<button onClick={this.force}>不更新任何状态中的数据,强制更新一下</button>
</div>
)
}
// 强制更新按钮的回调
force = ()=>{
this.forceUpdate();
}
add = ()=>{
let count = this.state.count;
count++;
this.setState({count:count});
}
death = ()=>{
ReactDOM.unmountComponentAtNode(document.getElementById('test'));
}
// 组件将要挂载时触发的钩子函数
componentWillMount(){
console.log('Count_componentWillMount');
};
// 组件挂载完成触发的钩子函数
componentDidMount(){
console.log('Count_componentDidMount');
}
// 组件将要卸载时触发的钩子函数
componentWillUnmount(){
console.log('Count_componentWillUnmout');
}
// 控制组件更新的“阀门”
shouldComponentUpdate(){
console.log('shouldComponentUpdate');
return true;
}
// 组件将要更新时触发的钩子函数
componentWillUpdate(){
console.log('Count_componentWillUpdate');
}
componentDidUpdate(){
console.log('Count_componentDidUpdate');
}
}
// 渲染组件
ReactDOM.render(<Count />,document.getElementById('test'));
</script>
</body>
</html>
强制更新时:不执行shouldComponentUpdate,
如果点击更新:
新的生命周期函数(生命周期钩子函数)
1.初始化阶段:由ReactDOM.render()触发——初次渲染
a.constructor()
b.getDerivedStateFromProps
c.render()
d.componentDidMount()
2.更新阶段:由组件内部this.setState()或父组件重新render触发
a.getDerivedStateFromProps
b.shouldComponentUpdate()
c.render()
d.getSnapshotBeforeUpdate
e.componentDidUpdate()
3.卸载组件:有ReactDOM.unmountComponentAtNode()触发
<!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>
<!-- 引入react核心库 -->
<script src="./js/17.0.1/react.development.js"></script>
<!-- 引入react-dom用于React操作dom -->
<script src="./js/17.0.1/react-dom.development.js"></script>
<!-- 引入babel -->
<script src="./js/17.0.1/babel.min.js"></script>
<script type="text/babel">
class Count extends React.Component{
constructor(props){
super(props);
console.log('Count_constructor');
}
state = {count:0};
render(){
console.log('Count_render');
let {count} = this.state;
return(
<div>
<h2>当前的值:{count}</h2>
<button onClick={this.add}>+1</button>
<button onClick={this.death}>卸载组件</button>
<button onClick={this.force}>不更新任何状态中的数据,强制更新</button>
</div>
)
}
add = ()=>{
let {count} =this.state;
count++;
this.setState({count:count});
}
// 页面强制更新数据
force = () =>{
this.forceUpdate();
}
death = ()=>{
ReactDOM.unmountComponentAtNode(document.getElementById('test'));
}
// 若state的值任何时候都取决于props
static getDerivedStateFromProps(props,state){
console.log('Count_getDerivedStateFromProps',props,state);
return null;
}
// // 组件将要挂载时的钩子函数
// UNSAFE_componentWillMount(){
// console.log('Count_componentWillMount');
// }
// 组件挂载完成时的钩子函数
componentDidMount(){
console.log('Count_componentDidMount');
}
// 组件将要卸载的钩子函数
componentWillUnmount(){
console.log('Count_componentWillUnmount');
}
// 控制组件更新的“阀门”
shouldComponentUpdate(){
console.log('Count_shouldComponentUpdate');
return true;
}
// 在更新之前获取快照
getSnapshotBeforeUpdate(){
console.log('Count_getSnapshotBeforeUpdate');
return 'charmer';
}
componentDidUpdate(){
console.log('componentDidUpdate');
}
}
// 渲染组件
ReactDOM.render(<Count props={100}/>,document.getElementById('test'));
</script>
</body>
</html>