react面试通

React面试百题通

小编比较追求原理可能有些枯燥,乏味还望读者见谅,但是看一下总对技术提高有好处。

Virtual Dom和Real Dom的区别分析

  1. 减少dom操作

    操作dom消耗是非常大的,虽然有可能读者没有感觉到,但是你如果想象一下你有10000个dom节点,通过浏览器提供api就需要操作10000次,但是虚拟dom只需要一次

  2. 更新区域最小化

    虚拟dom会通过diff算法,对比前后两次dom树的区别,从而更新最小范围的dom元素

  3. 在某种情况下虚拟dom性能比真实dom快

React的生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PojQdqb0-1617296391159)(C:%5CUsers%5Clin%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210320104824319.png)]

这是React 16.4 + 版本的生命周期函数,在react16前还存在三个方法

  • componentWillMount

  • componentWillReceiveProps

  • componentWillUpdate

    这三个生命周期在React16后被遗弃了

react的声明周期函数从宏观方面分为挂载时,更新时,卸载时

挂载阶段触发的生命周期函数:

  • constructor: 构造函数 初始化状态和属性

  • getDerivedStateFromProps:: 根据字面意思理解可以看出这个方法就是从props获取state,方法功能就是可以根据自己的意愿,控制从props获取的值

    ​ 例如:

      static getDerivedStateFromProps (props, state) {
        if(typeof props.list === 'object') { // 这里判断如果props的list是Object 则返回否则返回空 意义是说如果List不是对象则不传给子组件
          return {
            list: props.list,
          }
        }else {
          return null;
        }
      }
    
  • render: 渲染Dom节点

  • componentDidMount:

什么是虚拟dom(virtual dom)

虚拟dom:简答说就是用js对象来表示dom结构

例如:

<div id='app'>
   <span id='child'>1</span>
 </div>
 //转换成js对象
 const vnode = {
  tag:'div',
  attrs:{id:'app'},
  children:[{ tag:'span',attrs:{id:'child'},children:['1']}]
}

React中Context有什么作用

React中Context是组件之间用来传递数据的方法,并且这个传递还可以是跨层级的。

React中的Diff算法

传统的diff算法: 传统diff算法对比两颗树形结构,需要对比全部节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lewK1J4k-1617296391160)(C:%5CUsers%5Clin%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210328075629753.png)]

这样时间复杂度就已经达到O(n2)了,对比后还要逐一移动元素或者处理元素又是一个O(n)时间复杂度就达到O(n3)

react diff算法: react基于三个优化把时间复杂度降到O(n)

Tree diff 优化

在WEBUI在跨层级移动比较少,可以忽略不计,首先对virtual dom 进行层级比较,并且只比较父节点,如果父节点不在,则直接删除整个节点包括子节点,这样循环的时间复杂度为O(n),如果出现跨层级则对节点进行删除,重建,尽量避免跨层级因为开销比较大

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aN7uAZAx-1617296391162)(C:%5CUsers%5Clin%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210328085541698.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tqbnBj0S-1617296391164)(C:%5CUsers%5Clin%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210328090953029.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hrD6Gg5Y-1617296391165)(C:%5CUsers%5Clin%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210328091250780.png)]

Component diff 优化

首先也是层级比较

  • 如果是同一类型的组件,组件内的元素又是一个virtual Dom 树继续比较
  • 如果不是同一类型的组件,则判断为dirty component,直接替换整个组件以及所有的子节点

Element diff优化

同一层级比较,diff提供三种操作:删除、插入、移动

  • 当元素不在层级中则插入
  • 当元素已经改变无法复用则删除创建
  • 如果元素只是改变位置则移动位置,移动可以根据key加以区分

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wVXNoP0r-1617296391166)(C:%5CUsers%5Clin%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210328092155312.png)]

Hoc又称高阶组件

高阶组件:首先要知道什么是高阶组件,简单说就是一个函数接收一个组件做为参数,并且返回一个组件这样的函数就是高阶组件。

那么有什么用呢?

高阶组件的应用主要在:功能增强、添加行为、添加逻辑等

简单的高阶组件:

// 接收一个组件作为参数
const Hoc = (WrappedCompoent)=> {
  return (props) => { //返回一个组件  注意这里写成了函数组件 如果是class则  class 组件名  extends Compoent 同理
    return (
      <div className={'hocWrap'}>
        <WrappedCompoent {...props}></WrappedCompoent>
      </div>
    )
  }
}

高阶组件实现方式:

1.属性代理(props proxy)

属性代理主要: 操作props 、 组件与其他元素组合、抽离State

class SayGoodBye extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div className={'name'}>
        父组件:{this.props.greet}
      </div>
    )
  }
}

const  PropsProxy = function (WrappedCompoent) {
  //返回一个组件
  return class InnerCompoent extends Component{
    render() {
      const props = {
        ...this.props,
        greet: '改变后的props'
      }
      return <div>
        <WrappedCompoent {...props} ></WrappedCompoent>
      </div>
    }
  }
}

2.反向代理(inheritance inversion)

反向代理主要作用有: 渲染劫持、 操作dom

简单的例子:

const  inheritance = function (WrappedCompoent) {
  //返回一个组件
  return class extends WrappedCompoent { //这里继承了作为的函数的组 因此只需调用WrappedCompoent的render方法即可
    render() {
      return <div>
        {super.render()};
        <div>这里写上需要添加的东西</div>
      </div>
    }
  }
}

渲染劫持、操作dom

class SayGoodBye extends Component {
  constructor(props) {
    super(props);
    this.state = {
      greet: 'goodBye'
    }
  }
  render() {
    return (
      <div className={'name'}>
        父组件:{this.state.greet}
      </div>
    )
  }
}
const  inheritance = function (WrappedCompoent) {
  //返回一个组件
  return class extends WrappedCompoent { //这里继承了作为的函数的组 因此只需调用WrappedCompoent的render方法即可
    handleAlterState = ()=> {
      this.setState({
        greet: 'hello'
      })
    }
    render() {
      return <div>
        {
          this.state.greet === 'goodBye' ? super.render(): ''
        }
        <div className={'test'}>渲染劫持</div>
        <button onClick={this.handleAlterState}>点我修改状态</button>
        <pre>当前greet值为 :{this.state.greet}<br/>
            点击按钮后,修改state,随之父组件渲染消失
        </pre>
      </div>
    }
  }
}

jsx原理

jsx是一种编写语法也是一种文件格式,混合了html和javascript的代码,但是浏览器不认识这样的代码,浏览器只认识javascript的代码,从而React创建就必须把转化成浏览器能够认识的代码,这个过程称之为“转译”

React转译原理:

其实jsx文件都是通过调用函数React.createElement这个方法

React.createElement(type,attribues,[children])以此类推

参数:

​ type: string,

​ attribues: Object,

​ children: Array

例如:

<div className='box1'>
 	hello world!

</div>

转译后

React.createElement(
  'div',
  { className: 'box1' },
  'hello world!!'
);

再如

<div className='box1'>
 	hello world!
 	<p className='txt1'>test1</p>
 	文字
</div>

转译后

React.createElement(
  'div',
  { className: 'box1' },
  'hello world!!',  //第一个元素
  React.createElement(//第二个元素
      'p',
      { className: 'txt1' },
      'text',  
  ),
  '文字',  //第三个元素
);

以此类推下去,如果是第二个元素内又插入元素就是在第二次CreateElement的children多加上一个,有兴趣可以去babel上翻译看看babeljs跳转连接

什么是props和state,他们之间 有什么区别

react最主要的特性就是组件,可以将一个应用分解成多个组件,而组件中的数据流就是由Props和state控制。

props是一种react组件的一种属性,或者也可以说是一种组件之间传递数据的一种方式,而属性的值是由父组件由决决定的,并且最重要的特性props不可变

state:是react组件内部数据集,或者说是react私有数据也是可以的,state是可变的并且私有的,每个组件都有自己的state,并且改变后组件将根据新的状态重新渲染,除此之外state可以由外部决定例如 键盘输入、服务器获取数据等

总结一句话: props是不可变,数据由自己决定, state是可以变的,数据可以由外部来决定

ct最主要的特性就是组件,可以将一个应用分解成多个组件,而组件中的数据流就是由Props和state控制。

props是一种react组件的一种属性,或者也可以说是一种组件之间传递数据的一种方式,而属性的值是由父组件由决决定的,并且最重要的特性props不可变

state:是react组件内部数据集,或者说是react私有数据也是可以的,state是可变的并且私有的,每个组件都有自己的state,并且改变后组件将根据新的状态重新渲染,除此之外state可以由外部决定例如 键盘输入、服务器获取数据等

总结一句话: props是不可变,数据由自己决定, state是可以变的,数据可以由外部来决定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值