稀土掘金 稀土掘金

【框架对比】React和Vue的生命周期

一、react

react生命周期

包括:数据初始化、创建、挂载、更新、销毁

react生命周期在项目中的执行顺序

constructor() => componentWillMount() => render() => componentDidMount()

当更新执行直接执行以下:

componentWillReceiveProps (nextProps) => shouldComponentUpdate(nextProps,nextState) => componentWillUpdate (nextProps,nextState) => render() => componentDidUpdate(prevProps,prevState)

关闭页面组件最终都会销毁: componentWillUnmount ()

react新增的生命周期:

  1. getDerivedStateFromProps(nextProps, prevState)

  2. getSnapshotBeforeUpdate(prevProps, prevState)

强调几点:

  1. constructor()中完成了React数据的初始化,它接受两个参数:props和context,当想在函数内部使用这两个参数时,需使用super()传入这两个参数。注:只要使用了constructor()就必须写super(),否则会导致this指向错误

  2. render()中会插入jsx生成的dom结构,react会生成一份虚拟dom树,在每一次组件更新时,在此react会通过其diff算法比较更新前后的新旧DOM树,比较以后,找到最小的有差异的DOM节点,并重新渲染。

getDerivedStateFromProps()代替componentWillReceiveProps()

在 componentWillReceiveProps 中,一般会做以下两件事:

  1. 根据 props 来更新 state
  2. 触发一些回调,如动画或页面跳转等。

componentWillReceiveProps缺点:

  1. 会破坏 state 数据的单一数据源,导致组件状态变得不可预测
  2. 也会增加组件的重绘次数
  3. 更新state和触发回调都在componentWillReceiveProps中执行

getDerivedStateFromProps优点:

  1. getDerivedStateFromProps 中禁止了组件去访问 this.props,强制让开发者去比较 nextProps 与 prevState 中的值,以确保当开发者用到 getDerivedStateFromProps 这个生命周期函数时,就是在根据当前的 props 来更新组件的 state,而不是去做其他一些让组件自身状态变得更加不可预测的事情。

  2. 更新 state在getDerivedStateFromProps中,触发回调在componentDidUpdate中,使得组件整体的更新逻辑更为清晰

// before
componentWillReceiveProps(nextProps) {
  if (nextProps.isSuccess !== this.props.isSuccess) {
    this.setState({ 
      isLogin: nextProps.isSuccess,   
    });
  }
  if (nextProps.isSuccess) {
    this.close();
  }
}

// after
static getDerivedStateFromProps(nextProps, prevState) {
  if (nextProps.isSuccess !== prevState.isSuccess) {
    return {
      isLogin: nextProps.isSuccess,
    };
  }
  return null;
}

componentDidUpdate(prevProps, prevState) {
  if (!prevState.isSuccess && this.props.isSuccess) {
    this.close();
  }
}

getSnapshotBeforeUpdate()代替componentWillUpdate()

componentWillUpdate的常见用例:读取当前某个 DOM 元素的状态,并在 componentDidUpdate 中进行相应的处理

componentWillUpdate的缺点:

  1. 在 React 开启异步渲染模式后,在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同,这就导致在componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了

getSnapshotBeforeUpdate的优点:

  1. getSnapshotBeforeUpdate 会在最终的 render 之前被调用,也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的。
  2. 此生命周期返回的任何值都将作为参数传递给componentDidUpdate()

二、vue

vue生命周期

vue每个组件都是独立的,每个组件都有一个属于它的生命周期。

包括:数据初始化、创建、挂载、更新、销毁

vue生命周期在项目中的执行顺序

beforeCeate() => data() => created() => beforeMount() => mounted()

当更新会再created之后插入: beforeUpdate => updated

关闭页面组件最终都会销毁: beforeDestroy() => destroyed()

强调几点:

  1. beforeCeate在事件和生命周期钩子初始化前调用
  2. data的初始化是在created前完成数据观测(data observer)
https://github.com/vuejs/vue/blob/dev/src/core/instance/init.js

initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')

vue中内置方法属性的运行顺序(methods、computed、data、watch、props)

从源码可以知道: props => methods =>data => computed => watch

https://github.com/vuejs/vue/blob/dev/src/core/instance/state.js

export function initState (vm: Component) {
  vm._watchers = []
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)
  if (opts.methods) initMethods(vm, opts.methods)
  if (opts.data) {
    initData(vm)
  } else {
    observe(vm._data = {}, true /* asRootData */)
  }
  if (opts.computed) initComputed(vm, opts.computed)
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}

几点注意

  1. 异步请求最好在mounted中执行
  2. $refs获取dom元素,在$nextTick中执行
  3. $refs直接访问子组件的方法,可能有数据的延迟滞后的bug,可以采用异步回调的方式解决
handleAsync () {
   return new Promise(resolve=>{
       resolve(res)
   })
}
async handleShow() {
    await this.handleAsync().then(res=>{
    	this.$refs.child.fun(res);
    })
}

比较

相同点:

  1. react和vue异步请求都最好在挂载函数(componentDidMount和mounted)中执行
  2. 生命周期都包含:初始化、创建、挂载、销毁、更新
  3. 都是通过refs获取dom元素
  4. 都需要进行卸载和数据的销毁:setTimeout、setInterval、removeEventListener等

不同点:

  1. 更新过程挂载阶段生命周期不一样,react用新函数componentDidUpdate,vue还是用mounted
  2. 写法大不一样

www.jianshu.com/p/b331d0e4b…

哆哆女性网襄阳seo最新梦幻家园破解版湖北联通营业厅姓翁 起名西安模版网站建设吴江网站制作姓李起什么名字好鹏起名字公司微信互动营销推广起名带三点水乐乐地带成字取名起名大全在哪里可以学seo罗晋演的电视剧有哪些扬州网站建设公司周易排卦八卦免费算命网柘城到商丘最早的一辆是几点公司起名字寓意好的字两个字r2v下载阿五美食加盟十四画的字女孩起名大全用周公解梦官才宁波 制作网站好听成熟的微信昵称网站设计服务比较好建设企业网站平台哪家seo公司好女孩起名字李导引养生十二功法淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻不负春光新的一天从800个哈欠开始有个姐真把千机伞做出来了国产伟哥去年销售近13亿充个话费竟沦为间接洗钱工具重庆警方辟谣“男子杀人焚尸”男子给前妻转账 现任妻子起诉要回春分繁花正当时呼北高速交通事故已致14人死亡杨洋拄拐现身医院月嫂回应掌掴婴儿是在赶虫子男孩疑遭霸凌 家长讨说法被踢出群因自嘲式简历走红的教授更新简介网友建议重庆地铁不准乘客携带菜筐清明节放假3天调休1天郑州一火锅店爆改成麻辣烫店19岁小伙救下5人后溺亡 多方发声两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#青海通报栏杆断裂小学生跌落住进ICU代拍被何赛飞拿着魔杖追着打315晚会后胖东来又人满为患了当地回应沈阳致3死车祸车主疑毒驾武汉大学樱花即将进入盛花期张立群任西安交通大学校长为江西彩礼“减负”的“试婚人”网友洛杉矶偶遇贾玲倪萍分享减重40斤方法男孩8年未见母亲被告知被遗忘小米汽车超级工厂正式揭幕周杰伦一审败诉网易特朗普谈“凯特王妃P图照”考生莫言也上北大硕士复试名单了妈妈回应孩子在校撞护栏坠楼恒大被罚41.75亿到底怎么缴男子持台球杆殴打2名女店员被抓校方回应护栏损坏小学生课间坠楼外国人感慨凌晨的中国很安全火箭最近9战8胜1负王树国3次鞠躬告别西交大师生房客欠租失踪 房东直发愁萧美琴窜访捷克 外交部回应山西省委原副书记商黎光被逮捕阿根廷将发行1万与2万面值的纸币英国王室又一合照被质疑P图男子被猫抓伤后确诊“猫抓病”

哆哆女性网 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化