class类组件
初始化阶段
getDefaultProps
初始化 props,可以用 defaultProps 代替
getInitialState
初始化 state,一般写在 this.state = {} 中
componentWillMount
准备创建虚拟 DOM,组件挂载前
render
虚拟组件渲染,挂载
componentDidMount
虚拟组件已经挂载完成,可在此阶段更新 state,或者调用接口,处理监听事件,一般发送ajax请求,获取远程的数据放在该方法下边
更新阶段
componentWillReceiveProps
父组件更新引发子组件更新时调用
shouldComponentUpdate
布尔值,是否更新组件,用来做性能优化
如 shouldComponentUpdate 的返回值是 false,那么即便是调用了 this.setState() 方法,也不会重新渲染页面;反之,如果是 true,则会重新渲染页面,也就是重新执行一遍 render() 方法
componentWillUpdate
组件刚开始更新的时候,还未重新渲染 DOM 时触发
render
根据更新的 state 和 props 重新渲染页面
componentDidUpdate
组件完成更新,DOM 渲染完成
卸载阶段
componentWillUnmount
组件卸载时触发。在这个阶段可以消除一些定时器或事件。
如下代码所示,点击父组件卸载掉子组件,并清掉定时器
实例如下
/**
* @Son组件 子组件
*/
import React from "react"
import PropTypes from 'prop-types'
export default class Son extends React.Component{
state = {
num:0
}
public interval = 0
componentWillMount(): void{
console.log('componentWillMount=>准备创建虚拟 DOM,组件挂载前')
}
componentDidMount(): void {
console.log('componentDidMount=>虚拟组件已经挂载完成,可在此阶段更新 state,或者调用接口,处理监听事件,一般发送ajax请求,获取远程的数据放在该方法下边')
this.interval = setInterval(()=>console.log('步时开始'),1000)
}
componentWillReceiveProps(): void{
console.log('componentWillReceiveProps=>父组件更新引发子组件更新时调用')
}
shouldComponentUpdate():boolean{
/**
* 如 shouldComponentUpdate 的返回值是 false,那么即便是调用了 this.setState() 方法,也不会重新渲染页面;反之,如果是 true,则会重新渲染页面,也就是重新执行一遍 render() 方法
*/
return true
}
componentWillUpdate(): void{
console.log('componentWillUpdate=>组件刚开始更新的时候,还未重新渲染 DOM 时触发')
}
componentDidUpdate(): void{
console.log('componentDidUpdate=>组件更新完成Dom渲染完毕')
}
componentWillUnmount(): void {
console.log('componentWillUnmount=>组件卸载时触发。在这个阶段可以消除一些定时器或事件')
clearInterval(this.interval)
}
public numAdd = ()=>{
this.setState({
...this.state,
num:++this.state.num
})
}
render(){
console.log('render=>虚拟组件渲染,挂载/根据更新的 state 和 props 重新渲染页面')
const {fatherData} = this.props
return<>
我是子组件
{fatherData}
<button onClick={this.numAdd}>{this.state.num}++</button>
</>
}
}
Son.defaultProps = {
fatherData:'123'
}
Son.propTypes = {
//限制fatherData必传,且为字符串(PropTypes首字母必须大写)
fatherData: PropTypes.string.isRequired
}
/**
* @father组件 父组件
*/
import React, { createRef, ReactNode } from 'react'
/**引入子组件Son */
import Son from './components/son'
import './App.css'
export default class App extends React.Component{
state={
fatherData:'我是父组件传递过来的参数',
isSon:false
}
public isSonFn = ()=>{
this.setState({
...this.state,
isSon:!this.state.isSon
})
}
render(): ReactNode {
return<>
{/* 子组件 */}
<button onClick={this.isSonFn}>{this.state.isSon?'关闭子组件':'打开子组件'}</button>
<button onClick={()=>this.setState({...this.state,fatherData:'我是父组件传递过来的参数///'})}>修改父组件的数据</button>
<br />
{this.state.isSon?<Son />:''}
</>
}
}
函数组件生命周期
函数组件是没有像类组件一样的生命周期
/**
* @Son组件 子组件
*/
import React, { useCallback, useEffect, useState } from "react"
import PropTypes, { string } from 'prop-types'
const Son = ({fatherData=''})=>{
let [num,setNum] =useState(0)
let [num2,setNum2] =useState(0)
/**
*
*/
let interval: number | null | undefined = null
const numAdd = useCallback(()=>{
setNum(++num)
})
const numAdd2 = useCallback(()=>{
setNum2(++num2)
})
/**
* @用作数据监听
*
* @第一个参数是一个函数
* 当第二个参数的值发生改变就会被调用 一般不会使用@return
* @第二个参数是一个数组存放的是被监听的数据
* 当监听的数据发生改变就会执行第一个参数的函数
*/
useEffect(()=>{
console.log(num,'num更新')
},[num,num2])
/**
* @模拟生命周期
* 当第二个参数为空数组时 第一个参数函数执行的是组件挂载结束时@return 一个函数该函数在组件即将销毁前执行
*/
useEffect(()=>{
console.log('组件挂载完成=>调用接口,处理监听事件,一般发送ajax请求,获取远程的数据放在该方法下边')
interval = setInterval(()=>console.log('步时器开始'),1000)
return ()=>{
console.log('组件卸载时触发。在这个阶段可以消除一些定时器或事件')
clearInterval(interval)
}
},[])
return<>
{console.log('组件挂载1')}
我是子组件
{fatherData}
<button onClick={numAdd}>{num}++</button>
<button onClick={numAdd2}>{num2}++</button>
</>
}
export default Son
/**
* @father组件 父组件
*/
import React, { createRef, ReactNode } from 'react'
/**引入子组件Son */
import Son from './components/son'
import './App.css'
export default class App extends React.Component{
state={
fatherData:123,
isSon:false
}
public isSonFn = ()=>{
this.setState({
...this.state,
isSon:!this.state.isSon
})
}
render(): ReactNode {
return<>
{/* 子组件 */}
<button onClick={this.isSonFn}>{this.state.isSon?'关闭子组件':'打开子组件'}</button>
<button onClick={()=>this.setState({...this.state,fatherData:'我是父组件传递过来的参数///'})}>修改父组件的数据</button>
<br />
{this.state.isSon?<Son />:''}
</>
}
}