react知识点

15.x生命周期

avatar

  1. 挂载卸载过程
    1.1 constructor()
    1.2 componentWillMount()
    1.3 componentDidMount()
    1.4 componentWillUnmount ()
  2. 更新过程
    2.1 componentWillReceiveProps (nextProps)
    2.2 shouldComponentUpdate(nextProps,nextState)
    2.3 componentWillUpdate (nextProps,nextState)
    2.4 componentDidUpdate(prevProps,prevState)
    2.5 render()

16.x生命周期

avatar
React新增的生命周期(个人补充)

  1. getDerivedStateFromProps(nextProps, prevState)
  2. getSnapshotBeforeUpdate(prevProps, prevState)

super(props)

super(props)的作用就是在父类的构造函数中给props赋值一个对象this.props=props这样就能在它的下面定义你要用到的属性了,然而其他的由于没有传参就直接赋值为undefind

setState

  1. setstate在原生事件,setTimeout,setInterval,promise等异步操作中,state会同步更新,在React内部机制能检测到的地方, setState就是异步的。
  2. 在异步的函数里可以准确拿到更新后的 state,通过第二个参数 setState(partialState, callback) 中的 callback 拿到更新后的结果。

key为index的问题

注意:如果不存在添加/删除/排序操作, 用index没有问题

  1. 添加/删除/排序 => 产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低
  2. 如果item界面还有输入框 => 产生错误的真实DOM更新 ==> 界面有问题

解决:使用item数据的标识数据作为key, 比如id属性值

数据传递详情

  1. 父传子:props
  2. 子传父:子组件中通过this.props.事件名(参数)的方式向父组件传递参数,父组件中,事件名={this.事件名.bind(this)}
  3. 兄弟(组件A – 传值 –> 父组件 – 传值 –> 组件B)
    avatar

虚拟DOM

为了减少消耗性能的DOM操作,React 把真实 DOM 树转换成js对象树,也就是 Virtual DOM。每次数据更新后,重新计算 Virtual DOM,并和上一次生成的 Virtual DOM 做Diff计算对比,对发生 变化的部分做批量更新。

  • 当首次挂载组件时,按顺序执行 getDefaultProps、getInitialState、componentWillMount、 render 和 componentDidMount。
  • 当卸载组件时,执行 componentWillUnmount。
  • 当重新挂载组件时,此时按顺序执行 getInitialState、componentWillMount、render 和componentDidMount,但并不执行 getDefaultProps。
  • 当再次渲染组件时,组件接受到更新状态,此时按顺序执行 componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render 和 componentDidUpdate。

同一层级的子节点,可以通过唯一的 id 来进行区分,通过shouldComponentUpdate()来判断该组件是否需要进行diff算法分析。

super(props)

super(props)的作用就是在父类的构造函数中给props赋值一个对象this.props=props这样就能在它的下面定义你要用到的属性了,然而其他的由于没有传参就直接赋值为undefind,如果不写,某个构造函数中调用了某个访问props的方法,bug就很难定位了,强烈建议使用。

PureComponent

默认情况下,会对props和state进行浅比较,如果组件渲染过程中,新旧props和state是相等的,将不会执行render,不能使用shouldComponentUpdate方法

immutable

https://mp.weixin.qq.com/s/06GDG6mdaElTfzb5McMxFQ
https://blog.csdn.net/qq_42941302/article/details/111834035

在Rudux中因为深拷贝对性能的消耗太大了(用到了递归,逐层拷贝每个节点)。
但当你使用immutable数据的时候:只会拷贝你改变的节点,从而达到了节省性能。

React函数组件和类组件的区别

  1. 函数组件是一个纯函数,不能在组件中使用setState(),不能在函数组件中使用生命周期钩子,原因和不能使用state一样,所有的生命周期钩子都来自于继承的React.Component中。但是在react16.8版本中添加了hooks,使得我们可以在函数组件中使用useState钩子去管理state,使用useEffect钩子去使用生命周期函数。
  2. 类组件存在this指向的问题(使用bind(this)提前规避)
  3. 函数组件不会被实例化,整体渲染性能得到提升

setState是同步还是异步

setState 只在合成事件和钩子函数中是“异步”的(在组件中的onClick,生命周期函数或等都是属于它自定义的合成事件);在原生事件和 setTimeout 中都是同步的(addeventListener添加的,dom中的原生事件)。

Hook

  1. useState
    const [state, setState] = useState(initialState);
  2. useEffect
    2.1 当useEffect没有第二个参数时,相当于componentDidMount以及componentDidUpdate
    2.2 空数组,初始化调用一次之后不再执行,相当于componentDidMount
    2.3 一个或者多个值的数组,值其中任意一个值变化了都会触发该函数,相当于componentDidUpdate
    2.4 返回一个函数,相当于componentWillUnmout(return中)

    高阶组件

    用函数包裹,函数参数接受一个普通组件,并最终返回一个新组件,这个返回的新组件就叫做高阶组件

    react vue 区别

  3. 监听数据变化的实现原理不同
    Vue通过 getter/setter以及一些函数的劫持,能精确知道数据变化。

React默认是通过比较引用的方式(diff)进行的,如果不优化可能导致大量不必要的VDOM的重新渲染。为什么React不精确监听数据变化呢?这是因为Vue和React设计理念上的区别,Vue使用的是可变数据,而React更强调数据的不可变,两者没有好坏之分,Vue更加简单,而React构建大型应用的时候更加鲁棒。

  1. 数据流的不同
    Vue1.0中可以实现两种双向绑定:父子组件之间,props可以双向绑定;组件与DOM之间可以通过v-model双向绑定。Vue2.x中去掉了第一种,也就是父子组件之间不能双向绑定了(但是提供了一个语法糖自动帮你通过事件的方式修改),并且Vue2.x已经不鼓励组件对自己的 props进行任何修改了。

React一直不支持双向绑定,提倡的是单向数据流,称之为onChange/setState()模式。不过由于我们一般都会用Vuex以及Redux等单向数据流的状态管理框架,因此很多时候我们感受不到这一点的区别了。

相同点:

  1. 使用 虚拟DOM (Virtual DOM)

    为什么Virtual DOM的能提高页面渲染性能?
    Virtual DOM是一个映射真实DOM的JavaScript对象
    如果需要改变任何元素的状态,那么首先在Virtual DOM上进行改变(而不是直接改变真实的DOM)
    然后,计算新旧Virtual DOM之间的差别(算法)
    最后,根据这些差别对真实的DOM增加、删除、修改、移动。

  2. 提供了响应式 (Reactive) 和组件化 (Composable) 的视图组件。

  3. 中心思想相同:一切都是组件,组件实例之间可以嵌套。

  4. 每个组件都提供合理的钩子函数,可以让开发者定制化地去处理需求。

  5. 专注于核心库,而将其他功能如路由和全局状态管理交给相关的库。
    不同点

  6. 数据绑定: 单向、双向
    React: 基于JSX编码, 单向数据绑定, 不能直接更新状态数据,必须通过setState()更新指定数据
    Vue: 基于模板语法, 双向数据绑定, 直接更新data数据11.35. Vue中mixin与extend区别

  7. 模板管理:JSX、template模版
    Vue所有的模板使用的是近似常规HTML,只不过是新添加了一些属性