React 面试必知必会 Day4

你们好,我是 @洛竹javascript

本文首发于 洛竹的官方网站html

本文翻译自 sudheerj/reactjs-interview-questionsjava

本文同步于公众号洛竹早茶馆,转载请联系做者。node

1. createElement 和 cloneElement 的区别是什么?

JSX 元素将被转换为 React.createElement() 函数以建立 React 元素,这些元素将用于 UI 的对象表示。而 cloneElement 用于克隆元素并将新的 props 传递给它。react

课后扩展:git

2. React 中的状态提高是什么?

当多个组件须要共享相同的变化数据时,建议将共享状态提高到它们最接近的共同祖先。这意味着,若是两个子组件共享来自其父组件的相同数据,则将状态移到父组件,而不是在两个子组件中都保持内部状态。github

3. 组件生命周期有哪些不一样阶段?

组件生命周期具备三个不一样的生命周期阶段。面试

  1. Mounting: 组件已准备好安装在浏览器 DOM 中。这个阶段涵盖了生命周期方法 constructor()getDerivedStateFromProps()render()componentDidMount() 的初始化。
  2. Updating: 在此阶段,组件以两种方式进行更新,即发送新 props 和从 setState()forceUpdate() 更新状态。此阶段涵盖了getDerivedStateFromProps()shouldComponentUpdate()render()getSnapshotBeforeUpdate()componentDidUpdate() 生命周期方法。
  3. Unmounting: 在最后一个阶段,再也不须要该组件并从浏览器DOM上卸载该组件。 这个阶段包括 componentWillUnmount() 生命周期方法。

值得一提的是,在将更改应用于 DOM 时,React 内部具备阶段性概念。 它们分开以下api

  1. Render: 该组件将渲染而没有任何反作用。这适用于 Pure 组件,在此阶段,React 能够暂停、停止或从新启动渲染。
  2. Pre-commit: 在组件将更改实际应用于 DOM 以前,有一段时间可让 React 经过 getSnapshotBeforeUpdate() 从 DOM 中读取内容。
  3. Commit: React 与 DOM 一块儿工做并分别执行最终的生命周期:componentDidMount() 用于安装,componentDidUpdate() 用于更新,以及 componentWillUnmount() 用于卸载。

React 16.3+ (或者 在线交互版本)浏览器

React 16.3 以前的版本:

phases 16.2

4. React 生命周期有哪些?

React 16.3 之前的版本:

  • componentWillMount: 在渲染以前执行,用于根组件中的应用程序级别配置。
  • componentDidMount: 在首次渲染以后执行,全部 AJAX 请求,DOM 或状态更新以及设置事件侦听器都应在此执行。
  • componentWillReceiveProps: 在特定属性更新以触发状态转换时执行。
  • shouldComponentUpdate: 肯定是否要更新组件。默认状况下,它返回 true。若是你肯定在状态或属性更新后不须要渲染组件,则能够返回 false 值。这是提升性能的好地方,由于若是组件收到新的 props,它能够防止从新渲染。
  • componentWillUpdate: 当有属性或状态改变被shouldComponentUpdate() 确认并返回 true 时,在从新渲染组件以前执行。
  • componentDidUpdate: 一般,它用于响应属性或状态更改来更新 DOM。
  • componentWillUnmount: 它将用于取消任何传出的网络请求,或删除与该组件关联的全部事件侦听器。

React 16.3+ 版本

  • getDerivedStateFromProps: 在调用 render() 以前被调用,而且在每次渲染中都会被调用。对于须要派生状态的罕见用例,这是存在的。若是您须要派生状态 值得一读。
  • componentDidMount: 在首次渲染以后执行,而且全部 AJAX 请求、DOM 或状态更新以及设置事件侦听器都应在此发生。
  • shouldComponentUpdate: 肯定是否将更新组件。默认状况下,它返回 true。若是你肯定在状态或属性更新后不须要渲染组件,则能够返回 false值。这是提升性能的好地方,由于若是组件接收到新的属性,它能够防止从新渲染。
  • getSnapshotBeforeUpdate: 在将呈现的输出提交给 DOM 以前当即执行。此方法返回的任何值都将传递到 componentDidUpdate() 中。 这对于从 DOM(即滚动位置)捕获信息颇有用。
  • componentDidUpdate: 一般,它用于响应属性或状态更改来更新DOM。若是 shouldComponentUpdate() 返回 false,则不会触发。
  • componentWillUnmount: 它将用于取消任何传出的网络请求,或删除与该组件关联的全部事件侦听器。

5. 高阶组件是什么

高阶组件(HOC)是接收组件并返回新组件的函数。基本上,这是从 React 的组成性质衍生出来的一种模式。

咱们称它们为纯组件,由于它们能够接受任何动态提供的子组件,可是它们不会修改或复制其输入组件中的任何行为。

const EnhancedComponent = higherOrderComponent(WrappedComponent)
复制代码

HOC 能够用到不少场景中:

  1. 代码重用,逻辑和引导程序抽象。
  2. 渲染劫持。
  3. 状态抽象和操纵。
  4. props操做。

6. 如何为 HOC 组件 建立 props 代理?

您可使用属性代理模式添加或编辑传递给组件的属性,以下所示:

function HOC(WrappedComponent) {
  return class Test extends Component {
    render() {
      const newProps = {
        title: 'New Header',
        footer: false,
        showFeatureX: false,
        showFeatureY: true
      }

      return <WrappedComponent {...this.props} {...newProps} />
    }
  }
}
复制代码

课后扩展:

7. context 是什么?

Context 提供了一种经过组件树传递数据的方法,而不须要一层一层手动传递属性。

例如,须要由许多组件在应用程序中访问通过身份验证的用户,本地设置首选项,UI 主题等。

const {Provider, Consumer} = React.createContext(defaultValue)
复制代码

8. 什么是 children 属性?

Children 是一个 prop(this.props.children),容许你将组件做为数据传递给其余组件,就像你使用的任何其余 prop 同样。放置在组件的开始标记和结束标记之间的组件树将做为 children 道具传递给该组件。

React API 中有许多方法可做为该属性。其中包括 React.Children.mapReact.Children.forEachReact.Children.countReact.Children.onlyReact.Children.toArray

children 的简单用法以下所示:

const MyDiv = React.createClass({
  render: function() {
    return <div>{this.props.children}</div>
  }
})

ReactDOM.render(
  <MyDiv> <span>{'Hello'}</span> <span>{'World'}</span> </MyDiv>,
  node
)
复制代码

9. React 中如何写注释?

React JSX 中的注释和 JavaScript 的多行注释很像,可是用大括号括起来。

单行注释:

<div>
  {/* 这里是单行注释 */}
  {`Welcome ${user}, let's play React`}
</div>
复制代码

多行注释:

<div>
  {/* Multi-line comments for more than one line */}
  {`Welcome ${user}, let's play React`}
</div>
复制代码

10. 在 constructor 中给 super 函数传递 props 的目的是什么?

一个子类构造器在 super() 方法调用以前是没法拿到 this 引用的。这一样也适用于 ES6 中的 sub-classes。调用 super() 时传递 props 的主要是为了在子类的构造器中访问 this.props

传递 props:

class MyComponent extends React.Component {
  constructor(props) {
    super(props)

    console.log(this.props) // 打印 { name: 'John', age: 42 }
  }
}
复制代码

不传递 props:

class MyComponent extends React.Component {
  constructor(props) {
    super()

    console.log(this.props) // 打印 undefined

    // 可是 props 参数依然能够访问
    console.log(props) // 打印 { name: 'John', age: 42 }
  }

  render() {
    // 在 constructor 以外没有影响
    console.log(this.props) // 打印 { name: 'John', age: 42 }
  }
}
复制代码

上面的代码片断揭示了 this.props 仅在构造函数中有所不一样。在构造函数外部表现将是相同的。

更多信息能够参考 为何咱们要写 super(props) ?