reactjs不常见的面试提要

原创
2018/05/23 19:21
阅读数 1.6K

直接上内容:

首先是首页结构:

<div>
  <C/>
  <B>
    <E/>
    <D/>
  </B>
</div>

在index中有3个子组件,在3个组件的生命周期componentWillMount与componentDidMount调用顺序:

问的有些水平至少我用react这么长时间,从来没有考虑过这类问题.

首先先说结果:在控制台打印为:

和自己面试回答的结果是一样的.

首先需要提及的是js是顺序执行的,

componentWillMount是在挂载前执行的,这里会把所有的需要挂载的虚拟的dom挂载完成,也就是说只能先从父组件开始,打印的便是father > c > b > e >d;c与d的执行顺序则是按照js顺序执行的顺序来的

当所有组件的componentWillMount都执行完了之后,接下来是走下一个生命周期:componentDidMount:

这个生命周期与componentWillMount不同的是,最外层的父组件是最后执行componentDidMount的,因为需要渲染到浏览器了,所以父组件得放到最后一个执行,顺序找子组件,第一个找到的便是c,它先执行componentDidMount,然后到b,发现b里有组件,这样通过一层一层的递归形式便可以完成渲染到浏览器的一个过程,当然了,react内部的具体实现我没有具体去看过,我想fb设计的思路应该就是这样的.

OK,这个问题过了.

接下来第二个问题:

传值:

依然是上面的数据结构:我有一个值是在c组件里的,需要传递给b组件里的d组件里?

这个就不难了,可以通过中间组件b来传递,当然了最好的方式便是react-redux或者mobx;具体的实现过程略略略...

第三个问题:

组件render的问题:现在在父组件里有一个定时期不断更改页面的内容代码如下:

import React,{Component} from 'react';
import { connect } from 'dva';
import B from '../b/a'
import C from '../c/c'
import D from '../d/d'
import E from '../e/e'
class IndexPage extends Component{
  constructor(props){
    super(props);
    this.state={
      time2:11,
      timer:null
    };
  }

  componentDidMount(){
    console.log('father');
    let time2 = this.state.time2;
    setInterval(()=>{
      this.setState({
        time2:time2++
      })
    },2000)
  }
  componentWillMount(){
    console.log('will father')
  }
  render(){
    return(
      <div>
        <span>{this.state.time2}</span>
        <C/>
        <B>
          <E/>
          <D/>
        </B>
      </div>
    )
  }
}


export default connect()(IndexPage);

以上代码仅为示例,如果实际中用到setInterval一定要在unMount中卸载;

问:子组件B,C,D,E是否会调用render方法;

首先看结果:

这里涉及到一个术语reconciliation,你可能会觉得这样不是很傻吗,我又没有传递属性给子组件,那父组件更新会触发所有后代组件的重渲染过程不是很低效且没有意义吗?但是React不能检测到你是否给子组件传了属性,所以它必须进行这个重渲染过程(术语叫做reconciliation)。但是这不会使得react有多低效,因为reconciliation过程是执行的JavaScript,而重渲染的性能开销主要是更新DOM导致的,最后diff算法会介入,决定是否要真正更新DOM,JavaScript的执行速度很快的,所以即使父组件render会触发所有后代组件的render过程(reconciliation过程),这个效率也不会有太大影响。

然后又提及到了Component与pureComponent的区别:

pureComponent中的shouldComponentUpdate是帮你做了一层浅比较是,类似下面的代码:

function shouldComponentUpdate(nextProps, nextState){
    const cProps = this.props, cState = this.state;
    for(let key in nextProps){
        if(cProps[key] !== nextProps[key]) return true
    }
    for(let key in nextState){
        if(cState[key] !== nextState[key]) return true
    }
    
    return false;
}

pureComponent为什么使用:当组件更新时,如果组件的 props 和 state 都没发生改变, render 方法就不会触发,省去 Virtual DOM 的生成和比对过程,达到提升性能的目的.

而Component中没有进行这样的比较,也是可以在Component中添加上述的代码也便能实现.

人嘛,总是慢慢的成长的!感觉自己回答的一般+吧!面了1个多小时!感谢!

展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部