2022即将到来,前端发展非常迅速,现在的前端已经不再是写写简单的页面了,伴随着web大前端,工程化越来越火,也出现了很多框架。很多公司也不单单是使用单一的框架了,作为前端开发国内最火的两大框架,都是必须要掌握的。所以,我决定在这疫情肆虐的年底把React学习一下,也为自己将来找工作多一分竞争力...
学习阶段,如有不对之处,欢迎评论区留言,我及时更正
本文已连载,其它章节传送门⬇️
生命周期
React中只有class定义的类组件才会有自己的生命周期,在特定的阶段执行生命周期钩子函数,以便于我们更好的操作组件。React16.4版本开始废弃了一些钩子函数,新增了一些钩子函数,但常用的钩子函数并没有改变。
常用生命周期钩子函数
组件的状态分为三个阶段:挂载阶段、更新阶段、卸载阶段
挂载阶段
💡 挂载时主要执行三个钩子函数,它们的执行顺序:
constructor
>render
>componentDidMount
export default class Demo extends Component {
constructor(props) {
console.log('constructor函数执行了')
super(props)
this.state = {
count: 0
}
}
componentDidMount() {
console.log('componentDidMount函数执行了')
}
render() {
console.log('render函数执行了');
return (
<div>
<h1>当前显示count:{this.state.count}</h1>
</div>
)
}
}
-
constructor函数
constructor
钩子函数是类组件的构造器,会初始化我们的state数据,如果我们不需要初始化数据和绑定事件函数的this,也可以不写constructor
-
render函数
render
函数当数据初始化完成,组件开始执行render函数渲染我们的组件,主要抒写我们的组件结构 -
componentDidMount函数
componentDidMount
钩子函数会在我们dom创建成功,组件渲染完成后执行,我们可以在这里发送请求获取数据 ,操作DOM
更新阶段
💡 更新时主要执行render函数和componentDidUpdate 函数,组件接收新的props或调用了setState方法或者强制更新组件forceUpdate 都会触发这两个钩子的执行
更改下代码,点击按钮count+1 触发组件更新
export default class Demo extends Component {
constructor(props) {
console.log('constructor函数执行了')
super(props)
this.state = {
count: 0
}
}
handleClick = () => {
this.setState({
count: this.state.count + 1
})
}
componentDidMount() {
console.log('componentDidMount函数执行了')
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log(prevProps,prevState, snapshot)
console.log('componentDidUpdate函数执行了')
}
render() {
console.log('render函数执行了');
return (
<div>
<h1>当前显示count:{this.state.count}</h1>
<button onClick={this.handleClick}>+ 1</button>
</div>
)
}
}
componentDidUpdate
函数会在组件完成更新后执行,并且接收三个参数:prevProps
, prevState
, snapshot
,分别是更新之前的props
、state
和getSnapshotBeforeUpdate
钩子函数return的值
卸载阶段
卸载时组件会执行componentWillUnmount
钩子函数,我们可以在这里做一些清楚定时器之类的工作
不常用生命周期钩子函数
getDerivedStateFromProps
💡 此钩子函数每次挂载和更新阶段都会调用,表示从props得到一个派生的状态,根据官网的说明也就是state的值任何时候都取决于props,并且无法更改。需要注意的是此方法需要用static声明,因为此方法只能是组件本身调用而不是组件实例,并且需要返回一个对象或者null
static getDerivedStateFromProps(props,state) {
return {
count: 100
}
}
我们复用之前的例子,给组件新增一个钩子函数,分别在更新和挂载阶段调用此钩子看看页面count值的变化
我们可以看到组件挂载和更新阶段count的值始终是我们getDerivedStateFromProps
返回的值,适用于组件的值始终依赖props的时候,但react官网说明此派生状态会导致代码冗余,并使组件难以维护
shouldComponentUpdate
此钩子函数会在组件接收到新的props或者调用setState方法的时候执行,意思为是否更新组件。默认返回true,显示返回false可以阻断组件更新,render后面的钩子就不会调用了。
getSnapshotBeforeUpdate
💡 此钩子函数在组件最近一次更新之前执行,接收
prevProps
,prevState
两个参数。意思就是组件发生更新之前我们可以拿到一些信息,比如获取滚动位置等。注意:必须有返回值或者 null,并且此返回值会作为参数传递给componentDidUpdate
钩子函数
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
export default class Demo extends Component {
constructor(props) {
console.log('constructor函数执行了')
super(props)
this.state = {
count: 0
}
}
handleClick = () => {
this.setState({
count: this.state.count + 1
})
}
static getDerivedStateFromProps(props,state) {
console.log(props,state)
return {
count: 100
}
}
componentDidMount() {
console.log('componentDidMount函数执行了')
}
getSnapshotBeforeUpdate(prevProps,prevState) {
console.log(prevProps,prevState)
return {
count: 200
}
}
componentDidUpdate(prevProps,prevState, snapshot) {
console.log(prevProps,prevState, snapshot)
console.log('componentDidUpdate函数执行了')
}
render() {
console.log('render函数执行了');
return (
<div>
<h1>当前显示count:{this.state.count}</h1>
<button onClick={this.handleClick}>+ 1</button>
</div>
)
}
}
ReactDOM.render(<Demo name='小明'/>, document.querySelector('#root'))
可以看到第一个和第二个打印的是getDerivedStateFromProps
钩子函数接收的参数,拿到的都是现在的props和state;第三个打印的是getSnapshotBeforeUpdate
钩子函数的参数,拿到的是更新之前的props和state,并且此钩子函数返回了一个数据count:200;第四个打印是componentDidUpdate
钩子函数的参数,组件更新完毕了,拿到的是更新之前的props和state和getSnapshotBeforeUpdate
return的值。