前端react面试题实例代码分析

作者:有用网 阅读量:207 发布时间:2024-01-06
关键字 react

这篇“前端react面试题实例代码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“前端react面试题实例代码分析”文章吧。

    React中有使用过getDefaultProps吗?它有什么作用?

    通过实现组件的getDefaultProps,对属性设置默认值(ES5的写法):

    var ShowTitle = React.createClass({
      getDefaultProps:function(){
        return{
          title : "React"
        }
      },
      render : function(){
        return <h2>{this.props.title}</h2>
      }
    });

    React.Component 和 React.PureComponent 的区别

    PureComponent表示一个纯组件,可以用来优化React程序,减少render函数执行的次数,从而提高组件的性能。

    在React中,当prop或者state发生变化时,可以通过在shouldComponentUpdate生命周期函数中执行return false来阻止页面的更新,从而减少不必要的render执行。React.PureComponent会自动执行 shouldComponentUpdate。

    不过,pureComponent中的 shouldComponentUpdate() 进行的是浅比较,也就是说如果是引用数据类型的数据,只会比较不是同一个地址,而不会比较这个地址里面的数据是否一致。浅比较会忽略属性和或状态突变情况,其实也就是数据引用指针没有变化,而数据发生改变的时候render是不会执行的。如果需要重新渲染那么就需要重新开辟空间引用数据。PureComponent一般会用在一些纯展示组件上。

    使用pureComponent的好处:当组件更新时,如果组件的props或者state都没有改变,render函数就不会触发。省去虚拟DOM的生成和对比过程,达到提升性能的目的。这是因为react自动做了一层浅比较。

    React 事件机制

    <div onClick={this.handleClick.bind(this)}>点我</div>

    React并不是将click事件绑定到了div的真实DOM上,而是在document处监听了所有的事件,当事件发生并且冒泡到document处的时候,React将事件内容封装并交由真正的处理函数运行。这样的方式不仅仅减少了内存的消耗,还能在组件挂在销毁时统一订阅和移除事件。

    除此之外,冒泡到document上的事件也不是原生的浏览器事件,而是由react自己实现的合成事件(SyntheticEvent)。因此如果不想要是事件冒泡的话应该调用event.preventDefault()方法,而不是调用event.stopProppagation()方法。 JSX 上写的事件并没有绑定在对应的真实 DOM 上,而是通过事件代理的方式,将所有的事件都统一绑定在了 

    document
     上。这样的方式不仅减少了内存消耗,还能在组件挂载销毁时统一订阅和移除事件。

    另外冒泡到 

    document
     上的事件也不是原生浏览器事件,而是 React 自己实现的合成事件(SyntheticEvent)。因此我们如果不想要事件冒泡的话,调用 
    event.stopPropagation
     是无效的,而应该调用 
    event.preventDefault

    实现合成事件的目的如下:

    • 合成事件首先抹平了浏览器之间的兼容问题,另外这是一个跨浏览器原生事件包装器,赋予了跨浏览器开发的能力;

    • 对于原生浏览器事件来说,浏览器会给监听器创建一个事件对象。如果你有很多的事件监听,那么就需要分配很多的事件对象,造成高额的内存分配问题。但是对于合成事件来说,有一个事件池专门来管理它们的创建和销毁,当事件需要被使用时,就会从池子中复用对象,事件回调结束后,就会销毁事件对象上的属性,从而便于下次复用事件对象。

    React 高阶组件、Render props、hooks 有什么区别,为什么要不断迭代

    这三者是目前react解决代码复用的主要方式:

    • 高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。具体而言,高阶组件是参数为组件,返回值为新组件的函数。

    • render props是指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术,更具体的说,render prop 是一个用于告知组件需要渲染什么内容的函数 prop。

    • 通常,render props 和高阶组件只渲染一个子节点。让 Hook 来服务这个使用场景更加简单。这两种模式仍有用武之地,(例如,一个虚拟滚动条组件或许会有一个 renderltem 属性,或是一个可见的容器组件或许会有它自己的 DOM 结构)。但在大部分场景下,Hook 足够了,并且能够帮助减少嵌套。

    (1)HOC 官方解释∶

    高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。

    简言之,HOC是一种组件的设计模式,HOC接受一个组件和额外的参数(如果需要),返回一个新的组件。HOC 是纯函数,没有副作用。

    // hoc的定义
    function withSubscription(WrappedComponent, selectData) {
      return class extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            data: selectData(DataSource, props)
          };
        }
        // 一些通用的逻辑处理
        render() {
          // ... 并使用新数据渲染被包装的组件!
          return <WrappedComponent data={this.state.data} {...this.props} />;
        }
      };
    
    // 使用
    const BlogPostWithSubscription = withSubscription(BlogPost,
      (DataSource, props) => DataSource.getBlogPost(props.id));

    HOC的优缺点∶

    • 优点∶ 逻辑服用、不影响被包裹组件的内部逻辑。

    • 缺点∶ hoc传递给被包裹组件的props容易和被包裹后的组件重名,进而被覆盖

    (2)Render props 官方解释∶

    "render prop"是指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术

    具有render prop 的组件接受一个返回React元素的函数,将render的渲染逻辑注入到组件内部。在这里,"render"的命名可以是任何其他有效的标识符。

    // DataProvider组件内部的渲染逻辑如下
    class DataProvider extends React.Components {
         state = {
        name: 'Tom'
      }
    
        render() {
        return (
            <div>
              <p>共享数据组件自己内部的渲染逻辑</p>
              { this.props.render(this.state) }      </div>
        );
      }
    }
    
    // 调用方式
    <DataProvider render={data => (
      <h2>Hello {data.name}</h2>
    )}/>

    由此可以看到,render props的优缺点也很明显∶

    • 优点:数据共享、代码复用,将组件内的state作为props传递给调用者,将渲染逻辑交给调用者。

    • 缺点:无法在 return 语句外访问数据、嵌套写法不够优雅

    (3)Hooks 官方解释∶

    Hook是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。通过自定义hook,可以复用代码逻辑。

    // 自定义一个获取订阅数据的hook
    function useSubscription() {
      const data = DataSource.getComments();
      return [data];
    }
    // 
    function CommentList(props) {
      const {data} = props;
      const [subData] = useSubscription();
        ...
    }
    // 使用
    <CommentList data='hello' />

    以上可以看出,hook解决了hoc的prop覆盖的问题,同时使用的方式解决了render props的嵌套地狱的问题。hook的优点如下∶

    • 使用直观;

    • 解决hoc的prop 重名问题;

    • 解决render props 因共享数据 而出现嵌套地狱的问题;

    • 能在return之外使用数据的问题。

    需要注意的是:hook只能在组件顶层使用,不可在分支语句中使用。、

    React怎么做数据的检查和变化

    Model
    改变之后(可能是调用了
    setState
    ),触发了
    virtual dom
    的更新,再用
    diff
    算法来
    把virtual DOM
    比较
    real DOM
    ,看看是哪个
    dom
    节点更新了,再渲染
    real dom

    React实现的移动应用中,如果出现卡顿,有哪些可以考虑的优化方案

    • 增加

      shouldComponentUpdate
      钩子对新旧
      props
      进行比较,如果值相同则阻止更新,避免不必要的渲染,或者使用
      PureReactComponent
      替代
      Component
      ,其内部已经封装了
      shouldComponentUpdate
      的浅比较逻辑
    • 对于列表或其他结构相同的节点,为其中的每一项增加唯一

      key
      属性,以方便
      React
      diff
      算法中对该节点的复用,减少节点的创建和删除操作
    • render
      函数中减少类似
      onClick={() => {doSomething()}}
      的写法,每次调用render函数时均会创建一个新的函数,即使内容没有发生任何变化,也会导致节点没必要的重渲染,建议将函数保存在组件的成员对象中,这样只会创建一次
    • 组件的

      props
      如果需要经过一系列运算后才能拿到最终结果,则可以考虑使用
      reselect
      库对结果进行缓存,如果props值未发生变化,则结果直接从缓存中拿,避免高昂的运算代价
    • webpack-bundle-analyzer
      分析当前页面的依赖包,是否存在不合理性,如果存在,找到优化点并进行优化

    参考 前端进阶面试题详细解答

    在 React中元素( element)和组件( component)有什么区别?

    简单地说,在 React中元素(


    #发表评论
    提交评论