Skip to content

React 面试问题 #3

Description

@penouc

React 面试问题

以下是 React 常见的一些问题的列表。

React 是怎么工作的

React 创建虚拟 DOM 节点。 当组件中的 state 变化时,第一步会先执行 ‘diffing’ 算法,主要使用来识别虚拟 DOM 中哪些值发生了变化。第二步是调和,将 diff 之后结果去更新真实的 DOM 节点。

使用 React 给你带来了哪些好处

  • 如果想要知道一个组件是如何渲染的非常方便,只需要看这个组件的 render 函数即可
  • JSX 让你的代码更加易读。同时能让你更加清晰的知道布局的结构,以及模块之间是怎么组合的
  • 你可以使用 React 来进行服务端渲染,这将提高展示的性能,也便于做 SEO
  • 更加方便测试
  • 可以结合别的框架一起使用,比如 Backbone.js 或者 Angular.js,因为它仅仅只是一个视图层

展示组件和容器组件有什么区别

展示型组件的关注点是组件的样子(即骨架和样式),它们通常是接受props传来的数据并且执行相应的回调函数。这类组件几乎很好有自己的 state ,即使会用到的话通常也是使用在组件于组件的UI的状态( UI state ) ,而不是数据的状态( data state )。

容器型组件则更多的关注如何工作。这个类型的组件会生产一部分数据并且将它们展示出来或者传递给其他的容器组件。容器组件会调用 Flux 的 actions 并且将回调后的结果输出给展示组件。容器组件有时也会被当做一个数据源。

以 class 返回的组件和以函数返回的组件有什么区别

  • class 类型的组件允许你自由的为它添加特性,无论是本地的 state 或者是生命周期钩子。并且,也允许你的组件可以直接的访问你的 store 和它所包含的 state。
  • 当你的组件只是接受 props 并且把它们展示在页面上时,它们被称为「无状态组件」,它们就是一个纯函数。也被叫做哑组件(dumb components)或者是展示性组件。

state 和 props 有什么区别

state 会在组件 mount 时提供一个初始值。它会随着时间的变化儿变化(mutated),大部分都是作为用户事件的结果。
Props(即 properties 的缩写) 是一个组件的配置。他们通常由上面的组件传递,并且在当前组件接收到他们之前都是不可变的(immutable),一个组件不会改变它的 props 但是它通常是它的子组件的 props 的组合。Props不仅仅只包含数据 — 回调函数也会在 props 中传递。

生命周期以及生命周期所做的事情

  • componentWillMount - 通常用来在根组件中配置整个 App
  • componentDidMount - 这里你就可以做一些和DOM有关的处理了,因为这时DOM已经准备完毕,还有获取数据,以及绑定事件。这个生命周期钩子是干这些的好时机
  • componentWIlReceiveProps - 接受了props 导致 state 的变化
  • shouldComponentUpdate - 如果你在担心渲染的浪费,那「shouldComponentUpdate」是一个在你接受到新的 prop 时的同时你需要避免重复渲染并且提升性能的好地方,;「shouldComponentUpdate」总是返回一个布尔值,这个值决定你是否重新渲染这个组件
  • componentWillUpdate - 很少用,它可以用来替代「componentWillReceiveProps」并且它同时也包含「shouldComponentUpdate」(但是没有访问之前props的权限)
  • componentDidUpdate - 可以做一些DOM 有关的操作
  • componentWillUnmount - 这里你可以取消一个网络请求,或者移除掉与这个组件相关的事件

你会在 React 组件的哪里做 AJAX 请求

「componentDidMount」是最合适进行 AJAX 请求的地方。这个方法将会这个组件「mount」之后的第一时间执行,并且这个方法在整个生命周期中只会执行一次。更重要的是,如果是在组件「mount」之前执行的话,无法保证AJAX请求的准确完成时间,如果是那样的话,就意味着你可能在一个可能没有绑定上的组件上执行 setState ,这样肯定不会生效。在「componentDidMount」中执行AJAX请求组件一定会更新

什么是受控组件

在HTML中,表单元素比如<input><textarea>,和<select>通常拥有自己的状态并且响应用户的输入。当一个用户提交一个表单时前面提到的几个类型的元素的值都会和表单一起提交。但是React的工作方式是大不相同的。在一个React组件中,组件会时时刻刻跟踪用户输入值的变化并且在回调函数比如 onChange被触发state 更新的时候将组件进行重新渲染。一个输入表单元素它的输入值被React控制,所以我们叫它『受控组件』
受控组件通常会为表单元素添加 onSubmit 和 onChange 事件
我们如果使用内建的 form 表单则是使用的非受控组件,非受控组件通常和ref结合使用

在 React 里面怎么使用 refs

Refs 通常返回个真实的 DOM 节点或者一个 React 组件的实例。大量的使用refs的场景是需要管理 focus/ text selection,触发即时性要求较高的动画,或者调用第三方 DOM 库 api 。你应该避免直接使用refs 和 行内 ref 调用,React 推荐在回调中使用refs 。

什么是高阶组件

一个高阶组件是一个能接受一个旧的组件并返回一个新组件的函数。高阶组件允许你重用代码,逻辑以及初始化的抽象。使用得最多的地方应该是 react-redux 的connect函数。比共用通用工具和简单的组合更好,高阶组件很明显是一个更好的抽象React组件之间行为的方式。如果你正在不同的组件里面写着一些相同的东西,你也许可以考虑使用高阶组件将你的代码重构。
以下是些练习


  • 写一个将输入翻转的高阶组件
  • 写一个从某一个API获取数据并且传递给另一个组件的高阶组件
  • 写一个实现「shouldComponentUpdate」并且避免调和的高阶组件
  • 写一个使用React.Children.toArray将子节点排序,并且传递给另一个组件的高阶组件

使用箭头函数有什么好处

作用域安全:在箭头函数出现之前,每一个新建的新函数都拥有自己的this值(构造函数中是一个新的对象,严格模式下会返回undefined,在根对象上调用时会返回根对象),箭头函数不会返回自己的this,会使用最近的执行上下文中的this。紧凑:箭头函数方便理解阅读和书写
清楚:当很多的箭头函数嵌套时,开发人员可以很清楚的直接到最上层去找箭头函数中的this对象的指向即可

为什么相比于把回调函数传递 setState 传递一个对象更好呢

因为this.propsthis.state 也许会异步的更新,不能依赖这两个值来计算下一个state(next state).

怎么在 constructor 中绑定函数的 this 对象

你可以直接初始化的时候在函数后面绑定。这个是当你使用create-react-app时默认会添加的。也可以在函数中使用箭头函数,但是这样的话会导致每一次重新渲染都会创建一个新的函数。

如何阻止一个组件渲染

在组件的render方法中 return 一个 null 不会影响该组件其他生命周期的触发

在列表的渲染中 key 是什么,并且为什么需要这个 key

Key 能帮助 React 识别哪个元素改变了,是增加还是减少了。key 值在数据的列表渲染时必须是已经确定了的。给每一个元素赋 key 值是最好的能从一堆元素中选中一个元素的方式。大部分时候你可以使用ID作为Key。当你没有一个稳定的ID的时候 ,你也可以使用当前元素的索引值来当做key。但是并不推荐这么做,因为一旦这个列表发生了排序,这将会导致渲染变得非常的慢。

super(props) 有什么用

一个子组件的构造器在super()函数未被调用之前并不能使用 this 对象。同样的,ES2015 中如果一个类含有子类的话它也必须要调用super方法,原因是你必须传递 props 到 super 方法中,你才能在 constructor 中的 this 上访问 props。

什么是JSX

JSX 是 Javascript 语法的一个扩展,他拥有 Javascript 的全部语法。JSX 能生产 React 的「element」。你可以在任何地方通过小括号来使用返回React「element」。经过编译后,JSX会转义成一个普通的 Javascript 的对象。这意味着你能在任何的表达式中使用JSX,还有 for 循环中,给它绑定变量,将它作为参数传递,以及在函数中作为返回的对象。

React.createElement 的替代品是什么

Question:

const element = (
  \<h1 className="greeting"\>
Hello, world!
  \</h1\>
);

Answer:

const element = React.createElement(
  'h1',
  className: 'greeting',
  'Hello, world!'
);

什么是Children

this.props.children  是一个在传递给组件的信息中会自动添加的属性。React API 中有很多的方法可以对这个属性进行操作。包括 React.Children.map, React.Children.forEach, React.Children.count, React.Children.only, React.Children.toArray.
往组件中传入元素,即可取children

react 中的state是什么

state 有点类似于 props,但是 state 是私有的,并且单个 component 对这个属性拥有完全的控制权。本质上 state 是一个包含着控制着组件展示和行为相关所有数据的对象。

为什么你喜欢使用create-reacte-app来创建项目

因为这样就不用自己配置 webpack 和 babel 了

什么是 redux

Redux 的核心观点就是将整个应用的state保存在同一个store中。store 是一个简单的 Javascript 对象。修改 state 的唯一途径就是通过在应用中触发 actions 然后与这些 actions 关联的 reducer 能够改动 state。整个state状态的改变都需要通过 reducer 来改变并且同时不会带来别的副作用。

redux 中的 store 是什么

Store 是应用的 state 存储的位置。同时它还有以下的一些特性:

  • 允许获取到 state 通过 getState()
  • 允许更新 state 通过使用 dispatch(action)
  • 注册监听事件通过 subscribe(listener)
  • 取消注册监听事件通过调用 subscribe(listener) 返回的函数
  • 替换当前store中的reducer replaceReducer()

什么是action

Actions 都是普通的 JavaScript 对象。他们必须有个type字段来标志在执行的时候它是什么类型的。本质上,actions 就是把你应用中取到的有用的数据发送给store

什么是reducer

一个reducer是一个接受前一分state和action作为参数的纯函数,然后返回后一个state

Redux Thunk 的用途是?

Redux Thunk 是一个允许你写入一个action creator 的函数作为 action 的中间件。thunk 通常用来作为延迟执行dispatch 一个action的方法,这样就允许你异步的去 dispatching 一个action.

什么是纯函数

如果一个函数是纯函数,就意味着它不会依赖自身作用域之外的变量,也不会改变自身作用域之外的变量。这就意味着如果你输入一个值,不管如何变化,纯函数都会给出一个同样的返回值。

你喜欢 react 的哪些地方

你不喜欢 react 的哪些地方

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions