文章目录
一、React组件生命周期(新)
1.流程图
2.即将废弃的三个钩子
componentWillUpdate
componentWillMount
componentWillReceiveProps
前面应加上UNSAFE_
3.新增加的钩子
(1)getDerivedStateFromProps
前面要加static,必须要返回状态对象或null,能接收props,state
适用于state的值在任何时候都取决于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 crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<!-- 引入prop-types,用于对标签属性进行限制 -->
<!-- <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()
}
// 前面要加static,必须要返回状态对象或null,能接收props,state
// 适用于state的值在任何时候都取决于props的情况
static getDerivedStateFromProps=(props,state)=>{
console.log("getDerivedState")
return props
}
// 1.4组件挂载完毕的钩子
componentDidMount(){
console.log("Count-componentDidMount")
}
// 1.5组件将要卸载的钩子
componentWillUnmount(){
console.log("Count-componentWillUnmount")
}
// 2.1控制组件更新的阀门,默认返回值为真,返回值为真时可以更新,为假时状态不可以更新
shouldComponentUpdate(){
console.log("Count-shouldComponentUpdate")
return false
}
// 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>
(2)getSnapshotBeforeUpdate()
在更新之前获取快照
getsnapshotBefopdate(prevProps, prevstate)
getsnapshotBeforeupdate()在最近一次渲染输出(提交到 DOM 节点)之前调用。它便得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任同返回值将作为参数传递给 componentDidUpdate().
此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等。
组件更新完毕的钩子componentDidUpdate()能够接收三个参数,
preProps为之前的props,preState为之前的状态的,snapshotValue为getSnapshotBeforeUpdate组件的返回值 componentDidUpdate(preProps,preState,snapshotValue)
<!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 crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<!-- 引入prop-types,用于对标签属性进行限制 -->
<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()
}
// 前面要加static,必须要返回状态对象或null,能接收props,state
// 适用于state的值在任何时候都取决于props的情况
static getDerivedStateFromProps=(props,state)=>{
console.log("getDerivedState")
return null
}
// 在更新之前获取快照
getSnapshotBeforeUpdate=()=>{
console.log('getSnapshotBeforeUpdate')
return null
}
// 1.4组件挂载完毕的钩子
componentDidMount(){
console.log("Count-componentDidMount")
}
// 1.5组件将要卸载的钩子
componentWillUnmount(){
console.log("Count-componentWillUnmount")
}
// 2.1控制组件更新的阀门,默认返回值为真,返回值为真时可以更新,为假时状态不可以更新
shouldComponentUpdate(){
console.log("Count-shouldComponentUpdate")
return true
}
// 2.3组件更新完毕的钩子, 能够接收三个参数
componentDidUpdate(preProps,preState,snapshotValue){
console.log("Count-componentDidUpdate",preProps,preState,snapshotValue)
}
//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>
)
}
}
// const container = document.getElementById('test')
// const root = createRoot(container)
// root.render(<Count/>)
ReactDOM.render(<Count count={199}/>,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>
<style>
.list{
width: 200px;
height: 150px;
background-color: skyblue;
overflow: auto;
}
.news{
height:30px;
}
</style>
</head>
<body>
<div id= 'test'></div>
<div class ='list'>
<div class='news'>新闻1</div>
<div class='news'>新闻2</div>
<div class='news'>新闻3</div>
<div class='news'>新闻4</div>
<div class='news'>新闻5</div>
<div class='news'>新闻6</div>
</div>
<script type="text/javascript">
const list = document.getElementsByClassName('list')[0]
// 向下滚动30px
list.scrollTop=30
// 内容区的高度180
console.log(list.scrollHeight)
</script>
</body>
</html>
react案例
实现每隔1秒出现一条新闻,滑动时,新闻会停在当前页面,但是新闻依旧会不断增加
<!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>
<style>
.list{
height: 150px;
width: 200px;
background-color:skyblue;
overflow: auto;
}
.news{
height:30px;
}
</style>
</head>
<body>
<div id= 'test'></div>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<!-- 引入prop-types,用于对标签属性进行限制 -->
<script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.js"></script>
<script type="text/babel">
// 生命周期回调函数=生命周期钩子函数=生命周期函数=生命周期钩子
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() {
// console.log(this.refs.list.scrollHeight)
return this.refs.list.scrollHeight
}
componentDidUpdate(preProps,preState,height) {
// console.log(height)
// console.log(this.refs.list.scrollTop)
this.refs.list.scrollTop+=this.refs.list.scrollHeight-height
}
//1.3 render调用的时机:初始化渲染,状态更新之后
render(){
return (
<div className='list' ref="list">
{
this.state.newsArr.map((n,index)=>{
return <div key={index} className='news'>{n}</div>
})
}
</div>
)
}
}
ReactDOM.render(<NewsList />,document.getElementById('test'))
</script>
</body>
</html>
总结
提示:这里对文章进行总结:
1.初始化阶段:由ReactDom.render()触发—初次渲染
(1)constructor()
(2)getDerivedstateFromProps
(3)render()
(4)componentDidMount()==>常用
一般在这个钩子中做一些初始化的事,例如开启定时器,发送网络请求,订阅消息
2.更新阶段:由组件内部this.setsate()或父组件重新render触发
(1)getDerivedstateFromProps
(2)shouldcomponentUpdate()
(3)render() ==> 必须使用
(4)getsnapshotBeforeUpdate
(5)componentDidUpdate()
3.卸载组件:由ReactDoM.unmountcomponentAtNode()触发
componentWillUnmount()
常用,一般做一些收尾的事,例如:关闭定时器,取消订阅消息