引出生命周期
示例:文字透明度在组件渲染之后变化,点击按钮卸载组件示例
<!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>1-react生命周期</title>
</head>
<body>
<div id="root"></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/prop-types.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
class Test extends React.Component {
state = {
opacity: 0.5
}
componentDidMount() {
this.timer = setInterval(() => {
let { opacity } = this.state
opacity -= 0.1
if (opacity <= 0) opacity = 1
this.setState({ opacity })
}, 200);
}
componentWillUnmount() {
clearInterval(this.timer)
}
refuseStudy = () => {
ReactDOM.unmountComponentAtNode(document.getElementById('root'))
}
render() {
return (
<div>
<h1 style={{ opacity: this.state.opacity }}>react真简单,真好用</h1>
<button onClick={this.refuseStudy}>不学了</button>
</div>
)
}
}
ReactDOM.render(<Test />, document.getElementById('root'))
</script>
</body>
</html>
旧生命周期
组件挂载流程
constructor
componentWillMount
render
componentDidMount
按顺序执行
setState流程
- shouldComponentUpdate
控制组件更新的‘阀门’,一定要有返回值且是布尔类型,默认是true,设置为false即控制组件不再更新 - componentWillUpdate
- render
- componentDidUpdate
forceUpdate流程
- componentWillUpdate
- render
- componentDidUpdate
class Date extends React.Component {
fUpdate = () => {
this.forceUpdate()
}
componentWillUpdate() {
console.log('componentWillUpdate');
}
componentDidUpdate() {
console.log('componentDidUpdate');
}
render() {
console.log('render');
return (
<div>
<button onClick={this.fUpdate}>强制更新按钮</button>
</div>
)
}
}
ReactDOM.render(<Date />, document.getElementById('root'))
总结
初始化阶段
由ReactDOM.render() 触发 — 初次渲染
- constructor()
- conponentWillMount()
- render()
- componentDidMount() ===> 常用 做一些初始化的事:开启定时器、发送网络请求、订阅消息
更新阶段
由组件内部this.setState()或父组件render触发
- shouldComponentUpdate()
- componentWillUpdate()
- render() ===> 必用
- componentDidUpdate()
卸载阶段
由ReactDOM.unmountComponentAtNode()触发
- componentWillUnmount() ===> 常用 做一些收尾的事:清除定时器、取消订阅消息
新生命周期
getDerivedStateFromProps
getDerivedStateFromProps 必须是实例上的属性,是静态方法
特殊条件下使用:state的值任何条件下都取决于props
static getDerivedStateFromProps(props,state) {
console.log('getDerivedStateFromProps',props,state);
return props;
}
缺点:派生状态会导致代码冗余,使组件难以维护
getSnapshotBeforeUpdate
在更新之前获取快照,在最近一次渲染输出之前调用。使得组件能够在发生改动之前从DOM中捕获一些信息。此生命周期的任何返回值将作为参数传给componentDidUpdate()
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log('getSnapshotBeforeUpdate', prevProps, prevState);
return null;
}
getSnapshotBeforeUpdate举例
内容一直增加,scroll拉到哪里,就停止
class Date 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, height) {
this.refs.list.scrollTop += this.refs.list.scrollHeight - height
}
render() {
return (
<div className="list" ref="list">
{
this.state.newsArr.map((n,index)=>{
return (<div key={index} className="news">{n}</div>)
})
}
</div>
)
}
}
ReactDOM.render(<Date />, document.getElementById('root'))
总结
初始化阶段
由ReactDOM.render() 触发 — 初次渲染
- constructor()
- getDerivedStateFromProps()
- render()
- componentDidMount() ===> 常用 做一些初始化的事:开启定时器、发送网络请求、订阅消息
更新阶段
由组件内部this.setState()或父组件render触发
- shouldComponentUpdate()
- getSnapshotBeforeUpdate()
- render() ===> 必用
- componentDidUpdate()
卸载阶段
由ReactDOM.unmountComponentAtNode()触发
- componentWillUnmount() ===> 常用 做一些收尾的事:清除定时器、取消订阅消息