设为首页 加入收藏

TOP

React(v16.8.4)生命周期详解(一)
2019-09-17 15:38:51 】 浏览:25
Tags:React v16.8.4 生命 周期 详解

当前版本v16.8.4

装载过程(组件第一次在DOM树中渲染的过程):

constructor(常用) -> getInitialState(v16.0已废弃) -> getDefaultProps(v16.0已废弃) -> componentWillMount(v17.0中将被弃用) -> getDerivedStateFromProps(v16.3新增,并在v16.4中升级优化了一下) -> render(必须要) -> componentDidMount(常用)

更新过程(当组件被重新渲染的过程,state改变或props改变或父组件forceUpdate引发子组件的重新渲染):

componentWillReceiveProps(v17.0中将被弃用) -> getDerivedStateFromProps -> shouldComponentUpdate -> componentWillUpdate(v17.0中将被弃用) -> render -> getSnapshotBeforeUpdate -> componentDidUpdate

卸载过程(组件从DOM中删除的过程):

componentWillUnmount

错误处理(当组件发生错误的时候,用得极少)

getDerivedStateFromError(v16.6新增) -> componentDidCatch(未来将被废弃)

constructor:(可以不写,直接写state = {})

ES6中每个类的构造函数,并不是每个组件都需要定义自己的构造函数。比如无状态组件。
作用:

  1. 初始化state, 例如super(props)下的 this.state = {}
  2. 绑定成员函数的this环境。例如 this.onClickButton = this.onClickButton.bind(this)。但这种方案一般都会用箭头函数代替
    而综合以上两点作用,其实很多时候,你会在antd官网的例子上看到一些例子,并没有使用contructor, 而是直接简写为
  state = {
   count: 0
  }
  // 这是因为在ES6的继承中,其实不管子类写不写constructor,在new实例的过程都会给补上constructor
  class ColorPoint extends Point {
  
  }
  // 等同于 
  class ColorPoint extends Point {
    constructor(...args) {
      super(...args);
    }
  }

getInitialState: (随着v16.0版本createClass被弃用,该方法也不存在了)

返回值会用来初始化组件的this.state

getDefaultProps: (随着v16.0版本createClass被弃用,该方法也不存在了)

返回值可以作为props的初始值

componentWillMount:(即将在v17.0中被弃用,不用)

可以做:

  1. 直接使用setState改变组件状态,render会打印一次改变后的值(但是你这样做没什么意义,还不如直接在constructor的时候设好初始值)
  2. 发送Ajax请求(服务端渲染的时候)

不要做:

  1. 发送ajax请求(原因如下)
  2. 执行DOM操作(这个阶段DOM还没渲染出来)

最终建议:

不要用这个生命周期

在没被弃用的时候也几乎不用,这时候没有任何渲染出来的结果,即使调用this.setState修改状态也不会引发重新绘制。所有在这里可以做的事,都可以提前到 constructor中去做。有些人可能用过vue, 在vue中也经常在created中去请求接口,比如可能初始值是0,然后在created中请求接口,简单的理解成想页面在展示的时候就直接显示接口请求返回后的数据1了,而不是我们看到页面的时候先看到0,然后突然变成1了。个人理解vue的created和react的componentWillMount应该也是相差不了太多的,如果是在componentWillMount的时候你的数据还不是1的话,你这时候请求数据,其实是另外开了一个线程去执行异步操作了,render函数并不会等你异步请求结果返回1才去执行render。网络差的话,你先看到0再看到突然变成1也是很正常的事。在这里请求和在componentDidMount中请求并不会有太大的差别。同理,其实vue中特意区分该在created中还是mounted中请求接口也是没必要的,还不如统一到mounted/componentDidMount中去请求接口,因为我们有些方法还是要等真实dom存在后才去执行的。

getDerivedStateFromProps(props, state):

第一次在装载阶段(当前组件实例化)会被触发比较好理解,但是组件更新阶段,究竟组件更新阶段的什么操作会触发这个函数?
假如我在父组件改变了props 会触发这个函数吗?答案是会。
假如我在当前组件 this.setState 会触发这个函数吗?在v16.3中不会,但是在v16.4以上就会了。截至2019-03-17,在 https://react.docschina.org/docs/react-component.html#static-getderivedstatefromprops 上看到的翻译还是错的。不信可以自己试试?
假如我在父组件只是执行了 forceUpdate 强行引发一次重新绘制,那当前组件(子组件)的getDerivedStateFromProps又会被触发吗?
一样,在v16.3中不会,但是在v16.4以上就会了。
它返回一个对象来更新状态,如果返回的是null就表示不更新任何内容
这个方法react官方都意识到很多人对如何使用它存在许多误解(https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html),
目前很多人的博客其实写得也有点问题的。

render:(必须要)

返回一个JSX表示的对象,然后由React库来根据返回对象决定如何渲染。并不是返回的真实DOM,其他的生命周期都可以省,但是这个必须要

componentDidMount:(常用)

可以做:

  1. 发送ajax请求

不要做:

  1. 直接使用this.setState更新状态,这样会二次渲染(不过经常会有发送请求后,在回调函数里setState,这也是不可避免的)

仅在浏览器端执行,此时已经有了真实的dom节点,在这个阶段常用于处理接口请求,或者一些DOM操作。因为有些组件的启动动作是依赖DOM的,例如动画等。

需要注意的是:可以在这里发送异步请求,在回调函数里调用setState设置state。但是尽量不要在这里直接调用setState()设置状态。因为会触发一次额外的重新渲染,可能造成性能问题。

componentWillReceiveProps(nextProps):(即将在v17.0中被弃用,不用)

可以做:

  1. 根据props的更新同步组件状态。

不要做:

  1. 发送ajax请求
  2. 尤其是不要在这里setState

当前组件set

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇vue-cli 2.x和3.x安装的区别 下一篇jquery 获取上传文件大小

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目