组件生命周期函数

React 主动调用的方法,也可重写这些方法

生命周期图谱

当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:

constructor(props)

如果不需要初始化 state 或 不进行方法绑定,则不需要使用该方法

在组件挂载之前会先调用该方法,在实现构造函数时必须先调用super(props)方法,否则会出现BUG

通常,构造函数仅用于两种情况:1. 初始化 state 2. 为事件处理函数绑定实例

在该方法中不要使用 setState() 方法,在其他方法中使用setState()改变 state

为什么 props 复制给 state 会产生 bug

constructor(props) {
super(props);
// 不要在这里调用 this.setState()
this.state = {
counter: 0,
name:props.name // 严禁这样赋值,props.name值更新时 state.name并不会更新
};
this.handleClick = this.handleClick.bind(this);
}

static getDerivedStateFromProps() (此方法不常用)

此方法会在 render 方法之前调用,并且初始化和数据更新时都会调用,它返回一个对象更新 state,如果返回null 则不更新任何内容。

此方法适用于 state 值在任何时候都取决于props 的情况。

render()

render 是 class 组件必须实现的方法

当该方法被调用时,它会监测 props 和 state 的变化,并且返回以下类型之一:

  • React 元素:通过JSX创建,渲染成对应的DOM节点或自定义组件
  • 数组或fragments: 使render方法可以返回多个元素 frgments
  • Portals:可以渲染子节点到不同的DOM子树汇中portals
  • 字符串或数值类型: 在DOM中会被渲染为文本节点、
  • Boolean 或 null:什么都不渲染

render方法最好为纯函数,即在不修改组件 state情况下,每次调用时都返回相同的结果,并且不会直接与浏览器交互

如果要和浏览器交互,可以在其他生命周期函数中执行,注意:shoouldComponentUpdate方法中返回false,将不会调用render方法

class Example extemds React.Component{
shouldComponentUpdate(nextProps, nextState){
return false
}
render(){ // 不会执行
<div>owen</div>
}
}

componentDIdMount()

此方法会在组件挂载后(插入DOM树中)调用,初始化的数据的好地方

组件的 propsstate 发生变化会触发更新。组件更新的生命周期调用顺序如下:

static getDerivedStateFromProps() (此方法不常用)(已解释)

shouldComponentUpdate(nextProps, nextState) (此方法不常用)

当state 或 props 变化时该方法会在渲染执行前调用默认返回值为true,首次加载不会被调用

根据该方法的返回值判断组件输出是否受当前 state 或 props 更改的影响。默认为 state 每次更新重新渲染

此方法进仅做为性能优化的方式存在,不要企图依靠此方法来“阻止”渲染,因为这可能会产生 bug。你应该考虑使用内置的 PureComponent 组件,而不是手动编写 shouldComponentUpdate()。PureComponent 会对 props 和 state 进行浅层比较,并减少了跳过必要更新的可能性。

render()(已解释)

getSnapshotBeforeUpdate() (此方法不常用)

此方法在最近一次渲染输出(提交到DOM节点)之前调用。使组件能在发送更改前从DOM中捕获一些信息(如 位置)。此生命周期的返回值将作为参数传递给 componentDidUpdate()

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>
);
}
}

上述示例中,重点是从 getSnapshotBeforeUpdate 读取 scrollHeight 属性,因为 “render” 阶段生命周期(如 render)和 “commit” 阶段生命周期(如 getSnapshotBeforeUpdate 和 componentDidUpdate)之间可能存在延迟。

componentDidUpdate(prevProps, prevState, snapshot)

此方法会在数据更新后立即调用,首次加载不会被调用,在此方法中使用 setState必须将它放到条件语句中,否则会导致死循环。还会导致额外的重新渲染,影响性能

componentDidUpdate(prevProps) {
// 典型用法(不要忘记比较 props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}

注意:如果 shouldComponentUpdate() 返回值为 false,则不会调用 componentDidUpdate()。

当组件从 DOM 中移除时会调用如下方法:

componentWillUnmount()

此方法会在组件卸载销毁前调用,可以执行必要的清理操作,如 定时器,取消网络请求,或清除componentDidMount() 中创建的订阅等。

当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用如下方法:

Error boundaries:捕获渲染期间及整个树的函数发送的错误,渲染降级 UI,但自身的错误无法捕获 React 16中的错误处理

static getDerivedStateFromError(error) (此方法不常用)

次生命周期会在后代组件抛出错误后调用,将错误作为参数,返回一个值更新state,在渲染期间不允许出现副作用,建议使用 componentDidCatch()

componentDidCatch(error, info) (此方法不常用)

此方法在后代组件抛出错误后被调用

如果发生错误,可以通过调用 setState 使用 componentDidCatch() 渲染降级 UI,但在未来的版本中将不推荐这样做。 可以使用静态 getDerivedStateFromError() 来处理降级渲染。

class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
} static getDerivedStateFromError(error) {
// 更新 state 使下一次渲染可以显降级 UI
return { hasError: true };
}
componentDidCatch(error, info) {
// "组件堆栈" 例子:
// in ComponentThatThrows (created by App)
// in ErrorBoundary (created by App)
// in div (created by App)
// in App
logComponentStackToMyService(info.componentStack);
}
render() {
if (this.state.hasError) {
// 你可以渲染任何自定义的降级 UI
return <h1>Something went wrong.</h1>;
} return this.props.children;
}
}

Example

class Square extends React.Component {

  constructor(props) {
super(props);
this.state = {
value:null
};
}
static getDerivedStateFromProps(props, state) {
// 实例化组件之后以及在重新呈现组件之前调用新的静态生命周期。它可以返回要更新的对象state,或null指示新对象props不需要任何state更新。
}
componentDidMount() { // 组件被渲染到 DOM 中后运行
console.log('DidMount: 1')
} shouldComponentUpdate(){
// 更新前
} getSnapshotBeforeUpdate(){
//
}
componentDidUpdate() {
// 更新后
} static getDerivedStateFromError() {
// 出错时
}
componentDidCatch(){
// capture error
}
compoentwillUnmount(){ // 组件被删除的时候
console.log('UnMount: end') }
render() {
return (
<button className="square" onClick = {()=>{this.setState({value:'X'})}
}>
{this.state.value}
</button>
);
}
}

Owen 的个人博客

参考资料:React官网

Reactv16.8.6生命周期函数的更多相关文章

  1. Activity系列讲解---三大基本状态与七大生命周期函数

    简介:四大组件之一,在应用中一个Activity可以用来表示一个界面,可以理解为用户可视化界面,一个android应用必须通过Activity来运行和启动. 1.三大基本状态与七大生命周期函数 2.代 ...

  2. Cocos2d-x场景生命周期函数介绍

    层(Layer)的生命周期函数有如下: init().初始化层调用. onEnter().进入层时候调用. onEnterTransitionDidFinish().进入层而且过渡动画结束时候调用. ...

  3. ionic中的生命周期函数

    //ionic中的生命周期函数 onPageLoaded(){ //page初始化时 console.log("page 1 : page loaded"); } //在这里可以做 ...

  4. UIViewCotroller 的生命周期函数

    Viewcontroller 的所有生命周期函数 重写时 一定要先写 父类 方法 就是(super  +生命周期函数) LoadView ViewDidLoad ViewDidUnload: 在iOS ...

  5. 微信小程序 生命周期函数详解

    微信小程序 生命周期函数 小程序中 判断当前首页是从其他页面返回,还是由入口打开 由于小程序的数据在我们退出小程序时并没有得到释放,因此再次点击开来数据依然没有变成初始化 解决方法:在小程序 data ...

  6. React——组件的生命周期函数

    每一个组件都有一些生命周期函数. 当组件实例被创建并且会插入到DOM中,下面这些函数会被调用 constructor componentWillMount render componentDidMou ...

  7. Vue之生命周期函数和钩子函数详解

    在学习vue几天后,感觉现在还停留在初级阶段,虽然知道怎么和后端做数据交互,但是对对vue的生命周期不甚了解.只知道简单的使用,而不知道为什么,这对后面的踩坑是相当不利的.因为我们有时候会在几个钩子函 ...

  8. vue实例的生命周期函数

    Vue的生命周期函数通常分为以下三类: ①实例创建时的生命周期函数:②实例执行时的生命周期的函数:③实例销毁时的生命周期的函数. 代码与注释详解: <!DOCTYPE html> < ...

  9. vue(4)—— vue的过滤器,监听属性,生命周期函数,获取DOM元素

    过滤器 vue允许自定义过滤器,我个人认为,过滤器有两种,一种是对数据的清洗过滤,一种是对数据切换的动画过滤 数据切换的动画过滤 这里还是利用前面的动态组件的例子: 这里由于没办法展示动画效果,代码如 ...

随机推荐

  1. 宜信开源|手把手教你安装第一个LAIN应用

    LAIN是宜信公司大数据创新中心开发的开源PaaS平台.在金融的场景下,LAIN 是为解放各个团队和业务线的生产力而设计的一个云平台.LAIN 为宜信大数据创新中心各个团队提供了统一的测试和生产环境, ...

  2. 【POJ - 3414】Pots(bfs)

    Pots 直接上中文 Descriptions: 给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作 FILL(i)        将第i个容器从水龙头里装满(1 ≤ i ≤ 2); DRO ...

  3. ZooKeeper学习之路(二)—— Zookeeper单机环境和集群环境搭建

    一.单机环境搭建 1.1 下载 下载对应版本Zookeeper,这里我下载的版本3.4.14.官方下载地址:https://archive.apache.org/dist/zookeeper/ # w ...

  4. 【dockerFile配置jvm 启动参数】dockerFile 参数解释

    最近比较忙,实际也没有用得上.仅仅记录几个链接: Dockerfile reference:https://docs.docker.com/engine/reference/builder/#usag ...

  5. 渐进式web应用开发---service worker (二)

    阅读目录 1. 创建第一个service worker 及环境搭建 2. 使用service worker 对请求拦截 3. 从web获取内容 4. 捕获离线请求 5. 创建html响应 6. 理解 ...

  6. QT知识整理

    1.connect函数的SIGNAL可以是按键.定时器.其他对象的信号.如果是其他对象的信号,对象必须要在当前类中实例化. 2.Qt数据类型转换 1)int转QStringint a=10;QStri ...

  7. 简单学习之json格式说明

    json格式说明: 1.对象是一个无序的“‘名称/值’对”集合. (1)一个对象以“{”(左括号)开始,“}”(右括号)结束. (2)每个“名称”后跟一个“:”(冒号): (3)“‘名称/值’ 对”之 ...

  8. maven多仓库配置(公司服务器与阿里云仓库)

    1. 问题描述 公司内网搭建的有maven私有服务器,但是碰到好几次只有gav没有jar的情况或者最新版本更新不及时,所以需要公司服务器和远程仓库(阿里云)相结合来满足项目需求. 2. 解决方案: m ...

  9. Sending Operations to Multiple Threads_翻译

    The speed and efficiency of a long-running, data-intensive operation often improves when you split i ...

  10. 【AI】Android Pie中引入的AI功能

    前言 “无AI,不未来”,绝对不是一句豪情壮语,AI早已进入到了我们生活当中.去年Google发布的Android Pie系统在AI功能方面就做了重大革新,本文就对Google在新系统中引入的AI功能 ...