17.0
版本已经删除了的钩子函数(17.0
之前的版本仍可以继续使用):componentWillMount
,componentWillReceiveProps
,componentWillUpdate
UNSAFE_
import React ,{Component} from 'react'
import ReactDOM from 'react-dom'
// 子组件
class Child extends Component{
// 初始化数据
constructor(props){
super(props);
this.state = {};
}
// 当组件接收到新的props值会触发,新版已经淘汰
UNSAFE_componentWillReceiveProps(){
console.log("componentWillReceiveProps 运行了");
}
render(){
return(<div>子节点:{this.props.num}</div>)
}
}
class App extends Component {
constructor(props) {
console.log('constructor 运行了');
super(props);
this.state = {num:0};
}
// 组件挂载前,新版已经淘汰了
UNSAFE_componentWillMount(){
console.log('componentWillMount 运行了')
}
// 箭头函数
changeNum = ()=>{
this.setState({num:this.state.num+1})
}
// 渲染数据
render() {
console.log('render 运行了');
return (<div>
根节点<br/>
{/*
必须加/
*/}
<button onClick={this.changeNum}>++</button>{this.state.num}
<br/>子组件:
<Child num={this.state.num}/>
</div>);
}
// 组件更新前,新版已经淘汰了
UNSAFE_componentWillUpdate(){
console.log('componentWillUpdate 运行了');
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
增加了:static getDerivedStateFromProps()
和getSnapshotBeforeUpdate()
用来替代被弃用的旧版本那三个钩子函数
还增加了:static getDerivedStateFromError()
和componentDidCatch()
用来处理错误
import React ,{Component } from 'react'
import ReactDOM from 'react-dom'
class App extends Component {
constructor(props) {
console.log('constructor 运行了');
super(props);
this.state = {
count: 0
};
}
// 一般用不到:通过props设置获取到 state的值
// getDerivedStateFromProps前面要加上static保留字,声明为静态方法,不然会被react忽略掉
// getDerivedStateFromProps里面的this为undefined
static getDerivedStateFromProps(nextProps, prevState) {
console.log("getDerivedStateFromProps 运行了");
return true;
}
// 一般用不到:滚动的特殊处理,与componentDidUpdate 配对使用的
/* 在react `render()`后的输出被渲染到DOM之前被调用。
它使您的组件能够在它们被潜在更改之前捕获当前值(如滚动位置)。
这个生命周期返回的任何值都将作为参数传递给componentDidUpdate()*/
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("getSnapshotBeforeUpdate 运行了");
return 11;
}
componentDidUpdate(prevProps, prevState, snapState) {
console.log("componentDidUpdate 运行了", snapState);
}
// 本身或后代有报错会触发
componentDidCatch(error, info) {
console.log("componentDidCatch 运行了");
}
// 后代组件抛出错误后会触发
static getDerivedStateFromError(nextProps, prevState) {
console.log("getDerivedStateFromError 运行了");
}
// 定义事件
changeCount = () => {
this.setState({ count: this.state.count + 1 })
}
// 渲染数据
render(){
const { count} = this.state;
return(
<div>
<button onClick={this.changeCount}>++ {count}</button>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
import React, { Component } from 'react';
class App extends Component {
//初始化 ,state ,props,ref,绑定this
constructor(props) {
super(props);
this.state = {}
}
//渲染 ,父组件 执行了渲染,默认子组件的渲染函数也要执行
render() {
return (<div>首页</div>);
}
//是否需要更新 ,不需要 返回 false ;需要 返回true
shouldComponentUpdate() {
return true;
}
// DOM操作,实例化,数据请求
//异步处理,有副作用的处理 ;获取数据、执行 setTimeout setInterval
componentDidMount() {
console.log('componentDidMount')
}
//更新时的钩子函数
componentDidUpdate() {
console.log('componentDidUpdate')
}
//卸载 回收操作 定时器 解除绑定
componentWillUnmount() {
// 类似于vue 的beforeDestory
console.log('componentDidUpdate')
}
}
export default App;
componentDidMount
案例:实现文字透明度的渐变效果import React ,{Component} from 'react'
import ReactDOM from 'react-dom'
class App extends Component{
constructor() {
super();
this.state = {
opacity: 1 // 不透明
}
}
//在这个钩子函数中可以获取数据
componentDidMount(){
setInterval(()=>{
//报错,this指向不对,目前指向了window,可以使用箭头函数
let myOpacity = this.state.opacity;
myOpacity -= 0.05;
//如果透明度到0,重新置1
if(myOpacity<=0){
myOpacity = 1;
}
this.setState({
opacity:myOpacity
})
},500);
}
render() {
return (<>
<h1 style={{"opacity": this.state.opacity}}>hello world</h1>
</>);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
React中组件也有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个阶段,初始化(挂载)、运行中(更新)、销毁(卸载)、错误处理(异常)(16.3之后)
常用的生命周期方法就下面几个,为啥?因为好记,好记才会常用。程序员的本性。
其实其他生命周期方法也好用,但是需要特地条件下使用才会觉得方便。所以就不太常用
constructor()
render()
componentDidMount()
componentDidUpdate()
componentWillUnmount()
getDerivedStateFromProps
constructor
static getDerivedStateFromProps
render
componentDidMount
render()
使用方法
this.props
和this.state
,并返回以下一种类型:返回的类型 | 描述 |
---|---|
React元素 | 通常通过 JSX 创建,比如DOM元素或组件 |
数组 或 fragments | 使得 render 方法可以返回多个元素。 |
Portals | 可以渲染子节点到不同的 DOM 子树中 |
字符串或数值 | 它们在 DOM 中会被渲染为文本节点 |
null 或 布尔值 | 什么都不渲染。 |
使用限制
render()
方法必须是一个纯函数state
注意:
shouldComponentUpdate()
返回false
constructor(props)
constructor(props) {
super(props);
this.state = {
isLiked: props.isLiked
};
}
constructor使用条件
super(props)
props
绑定到这个类中this.props
将会无法得到constructor作用
this.state
赋值对象来初始化内部 state
constructor()在以下条件可以不用:
constructor()中不要这样做:
componentDidMount()
static getDerivedStateFromProps(nextProps, prevState)
Father.jsx
import React, { Component } from "react";
import Son from "./Son";
class Father extends Component {
render() {
return (
<div>
<Son val={1423}></Son>
</div>
);
}
}
export default Father;
Son.jsx
import React, { Component } from "react";
class Son extends Component {
// 初始化状态
state = {
num: 0,
a: 0
};
render() {
return (
<div>
<div>子组件:当前自身的state是{this.state.num}</div>
<button onClick={this.ck.bind(this)}>给a+1</button>
</div>
);
}
// 场景:希望本组件自身的状态与props同步,这个时候就可以使用getDerivedStateFromProps周期
static getDerivedStateFromProps(props, state) {
console.log('走了xxxxx');
// 在这里进行赋值
if (props.val === state.num) {
// 相等,不需要赋值
return null;
} else {
// 不相等,则需要赋值
return {
num: props.val,
};
}
}
ck() {
this.setState((state) => {
return {
a: state.a + 1,
};
});
}
}
export default Son;
static getDerivedStateFromProps
shouldComponentUpdate
render
getSnapshotBeforeUpdate
componentDidUpdate
componentDidUpdate(prevProps, prevState, snapshot)
componentDidUpdate()用法
与componentDidUpdate()联用
getSnapshotBeforeUpdate()
生命周期componentDidUpdate()
。undefined
。与shouldComponentUpdate()联用
shouldComponentUpdate(nextProps, nextState)
state
和props
的影响。shouldComponentUpdate
会在渲染执行之前被调用shouldComponentUpdate() 返回 false
componentWillUpdate
、render
和componentDidUpdate
不会被调用。getSnapshotBeforeUpdate(prevProps, prevState)
作用地点:
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
// 我们是否在 list 中添加新的 items ?
// 捕获滚动位置以便我们稍后调整滚动位置。
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// 如果我们 snapshot 有值,说明我们刚刚添加了新的 items,
// 调整滚动位置使得这些新 items 不会将旧的 items 推出视图。
//(这里的 snapshot 是 getSnapshotBeforeUpdate 的返回值)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}
componentWillUnmount()
componentDidMount
中创建的任何监听componentDidMount
中手动创建的DOM元素componentDidCatch(error, info)
static getDerivedStateFromError(error)