1.什么是生命周期
-
生命周期就是组件从创建到销毁的过程
-
生命周期钩子函数:生命周期的每个阶段总是伴随着一些方法的调用,这些方法就叫生命周期的钩子函数,生命周期的钩子函数为我们在不同阶段操作组件提供了时机
-
只有类组件才有生命周期
2.生命周期三个阶段
-
React组件的生命周期分为三个阶段:创建阶段,更新阶段,卸载阶段
-
每个阶段常用的钩子函数及触发时机
3.常用的生命周期钩子函数
-
创建阶段(组件创建时)
执行顺序:constructor---->render---->componentDidMount
-
constructor
时机:创建组件时最先执行
作用:1:初始化state 2:为事件处理程序绑定this
-
render
时机:每次组件渲染都会触发
作用:渲染视图(注意:不能调用setState)
-
componentDidMount
时机:组件挂载(完成DOM渲染后)
作用:1:发送网络请求 2:DOM操作
-
代码
import { Component } from "react";
class App extends Component {
constructor() {
super() // this
console.log('constructor')
}
render() {
console.log('render')
return (
<div id="app">
<h1>App组件</h1>
</div>
)
}
componentDidMount() {
console.log('componentDidMount')
}
}
export default App
-
更新阶段
使用this.setState更新状态的时候
组件的props属性发生变化的时候
强制更新,调用forceupdate()
执行顺序:render---->componentDidUpdate
-
render
时机:每次组件渲染都会触发
作用:渲染视图(注意:不能调用setState)
-
componentDidUpdate
时机:组件更新完成DOM渲染后
作用:1:发送网络请求 2:DOM操作
注意:如果要setState() 必须放在一个if操作中
-
代码
import { Component } from "react";
class Child extends Component {
state = {
count: 0,
}
render() {
console.log('render', 'Child')
return (
<div className="app-root">
<h1>Child组件</h1>
<button onClick={this.plus}>count+2</button>
<hr></hr>
<div>{this.props.num}-----{this.state.count}</div>
</div>
)
}
componentDidUpdate(prevProps, prevState) {
// prevProps 更新之前的props的值
// preState 更新之前的state的值
// 我们可以对比更新之前的props和state和更新之前的props和state是否一致,来决定是否调用setState
console.log('componentDidUpdate')
console.log(prevProps, this.props)
console.log(prevState, this.state)
}
plus = () => {
this.setState({
count: this.state.count + 5
})
}
}
export default Child
-
卸载阶段
-
componentWillMount
时机:组件卸载(从页面中消失)
作用:执行清理工作(清理定时器以及事件)
-
父组件
import { Component } from "react";
import Child from "./Child.js";
class App extends Component {
constructor() {
super() // this
this.state = {
num: 10,
isshow: true,
}
}
render() {
return (
<div id="app">
<h1>App组件</h1>
<button onClick={this.toggle}>切换</button>
{
this.state.isshow ? <Child num={this.state.num}></Child> : null
}
<button onClick={this.add}>更改num</button>
</div>
)
}
toggle = () => {
this.setState({
isshow: !this.state.isshow
})
}
add = () => {
this.setState({
num: this.state.num + 1
})
}
}
export default App
子组件
import { Component } from "react";
class Child extends Component {
state = {
count: 0,
}
render() {
console.log('render', 'Child')
return (
<div className="app-root">
<h1>Child组件</h1>
<button onClick={this.plus}>count+2</button>
<hr></hr>
<div>{this.props.num}-----{this.state.count}</div>
</div>
)
}
componentDidUpdate(prevProps, prevState) {
// prevProps 更新之前的props的值
// preState 更新之前的state的值
// 我们可以对比更新之前的props和state和更新之前的props和state是否一致,来决定是否调用setState
console.log('componentDidUpdate')
console.log(prevProps, this.props)
console.log(prevState, this.state)
}
componentWillUnmount() {
console.log('componentWillUnmount')
}
plus = () => {
this.setState({
count: this.state.count + 5
})
}
}
export default Child
4.不常用的生命周期钩子函数
-
static getDerivedStateFromProps
-
getDerivedStateFromProps属于静态方法,所以不能在该方法中访问实例
-
执行时机:组件创建、更新时
-
执行顺序:该方法在render方法之前执行
-
该方法必须返回一个对象来更新state,如果返回null则不更新任何内容
-
static getDerivedStateFromProps(props,state)
-
App.js
import { Component } from "react";
import List from './List.js'
import FooterCmp from './FooterCmp.js'
class App extends Component {
state = {
arrList: [
{ id: 1, checked: false, name: 'aaaa' },
{ id: 2, checked: false, name: 'bbbb' },
{ id: 3, checked: false, name: 'cccc' },
{ id: 4, checked: false, name: 'dddd' },
{ id: 5, checked: false, name: 'eeee' },
]
}
render() {
return (
<div id="app">
<List arrList={this.state.arrList} handleList={this.handleChange}></List>
<FooterCmp arrList={this.state.arrList} chooseAll={this.chooseAll}></FooterCmp>
</div>
)
}
handleChange = (id) => {
const copyArrList = [...this.state.arrList]
const idx = copyArrList.findIndex(item => item.id === id)
copyArrList[idx].checked = !copyArrList[idx].checked
this.setState({
arrList: copyArrList
})
}
// 全选
chooseAll = (checked) => {
const copyArrList = [...this.state.arrList]
copyArrList.forEach(item => {
item.checked = checked
})
this.setState({
arrList: copyArrList
})
}
}
export default App
List.js
import { Component } from "react";
class List extends Component {
render() {
return (
<div>
{this.props.arrList.map(item => (
<div key={item.id}>
<input type="checkbox" checked={item.checked} onChange={(ev) => (this.handleChange(item.id))} />
{item.name}
</div>
))}
</div>
)
}
handleChange = (id) => {
this.props.handleList(id)
}
}
export default List
FooterCmp.js
import { Component } from "react";
class FooterCmp extends Component {
state = {
checked: false
}
static getDerivedStateFromProps(nextProps, nextState) {
// nextProps 下一次的props属性值
// nextState 下一次的state属性值
// 当父组件传递过来的arrList数组发生变化时,返回最新的state
return {
checked: nextProps.arrList.every(item => item.checked)
}
}
render() {
return (
<div>
全选:
<input
type="checkbox"
checked={this.state.checked}
onChange={this.changeChecked} />
</div>
)
}
changeChecked = (ev) => {
this.props.chooseAll(ev.target.checked)
// 更改state中checked的值
}
}
export default FooterCmp
-
shoundComponentUpdate
-
组件重新渲染前执行
-
根据shoundComponentUpdate的返回值来决定是否更新自身组件以及子组件,返回true更新,返回false不更新
-
此方法作为性能优化的一种方案,不能企图依赖该方法来阻止渲染
-
最好使用React提供的内置组件PureComponent来自动判断是否调用render方法,而不是使用shoundComponentUpdate方法来进行手动判断
-
不建议在shoundComponentUpdate中进行深层比较或者使用JSOM.stringify
-
shoundComponentUpdate(nextProps, nextState)
nextProps更新完成后的props的值
nextState更新完成后的state的值
-
代码
import { Component } from "react";标签:生命周期,checked,render,Component,React,state,props,组件 From: https://www.cnblogs.com/toufuwqm/p/16916880.html
class App extends Component {
state = {
num: 0
}
shouldComponentUpdate(nextProps, nextState) {
// 判断上一次的state和更新后的state是否相等,来决定是否调用render更新组件
return nextState !== this.state.num
}
render() {
console.log('render')
return (
<div id="app">
<button onClick={this.handleClick}>点我</button>
<h1>父组件</h1>
<div>{this.state.num}</div>
</div>
)
}
handleClick = () => {
this.setState({
num: parseInt(Math.random() * 3)
})
}
}
export default App