React

1) React 中 keys 的作用是什么?

  • Keys 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。
render () {return (<ul>{this.state.todoItems.map(({item,i}) => {return <li key={i}>{item}</li>})}</ul>)
}
  • 在开发过程中,我们需要保证某个元素的 key 在其同级元素中具有唯一性。

    • 在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染;
    • 此外,React 还需要借助 Key 值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中 Key 的重要性。

2) 调用 setState 之后发生了什么?

  • 代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。

    • 经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面;
    • 在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染;
    • 在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

3) react 生命周期函数

  • 初始化阶段:

    • getDefaultProps:获取实例的默认属性
    • static propTypes 设置属性的类型
    • componentWillMount:组件即将首次被装载、渲染到页面上
    • render:组件在这里生成虚拟的 DOM 节点
    • componentDidMount:组件真正在被首次装载之后
  • 运行中状态:
    • componentWillReceiveProps:在数据更新页面需要重新渲染的时候,组件将要接收到属性的时候调用,
    • shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回 false,接收数据后不更新,阻止 render 调用,后面的函数不会被继续执行了)
    • componentWillUpdate:组件即将更新不能修改属性和状态
    • render:组件重新描绘
    • componentDidUpdate:组件已经更新
  • 销毁阶段:
    • componentWillUnmount:组件即将销毁

3.1) shouldComponentUpdate 是做什么的,(react 性能优化是哪个周期函数?)

  • shouldComponentUpdate

    • 询问组件是否需要更新的一个钩子函数,判断数据是否需要重新渲染,返回一个布尔值。默认的返回值是true,需要重新render()。若如果返回值是false则不触发渲染,利用这个生命周期函数可以强制关闭不需要更新的子组件来提升渲染性能。
    • 这个方法用来判断是否需要调用 render 方法重新描绘 dom。
      • 因为 dom 的描绘非常消耗性能,如果我们能在 shouldComponentUpdate 方法中能够写出更优化的 dom diff 算法,可以极大的提高性能。

4) 为什么虚拟 dom 会提高性能?(必考)

  • 虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。
  • 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。

5) react diff 原理(常考,大厂必考)

  • 把树形结构按照层级分解,只比较同级元素。
  • 列表结构的每个单元添加唯一的 key 属性,方便比较。
  • React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)
  • 合并操作,调用 component 的 setState 方法的时候, React 将其标记为 dirty.到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制.
  • 选择性子树渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能。

6) React 中 refs 的作用是什么?

  • Refs 是 React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄。

    • 我们可以为元素添加 ref 属性然后在回调函数中接受该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返回:
class CustomForm extends Component {handleSubmit = () => {console.log("Input Value: ", this.input.value)}render () {return (<form onSubmit={this.handleSubmit}><inputtype='text'ref={(input) => this.input = input} /><button type='submit'>Submit</button></form>)}
}
  • 上述代码中的 input 域包含了一个 ref 属性,该属性声明的回调函数会接收 input 对应的 DOM 元素,我们将其绑定到 this 指针以便在其他的类函数中使用。
  • 另外值得一提的是,refs 并不是类组件的专属,函数式组件同样能够利用闭包暂存其值:
function CustomForm ({handleSubmit}) {let inputElementreturn (<form onSubmit={() => handleSubmit(inputElement.value)}><inputtype='text'ref={(input) => inputElement = input} /><button type='submit'>Submit</button></form>)
}

7) 如果你创建了类似于下面的 Twitter 元素,那么它相关的类定义是啥样子的?

<Twitter username='tylermcginnis33'>{(user) => user === null? <Loading />: <Badge info={user} />}
</Twitter>
import React, { Component, PropTypes } from 'react'
import fetchUser from 'twitter'
// fetchUser take in a username returns a promise
// which will resolve with that username's data.
class Twitter extends Component {// finish this
}
  • 如果你还不熟悉回调渲染模式(Render Callback Pattern),这个代码可能看起来有点怪。
  • 这种模式中,组件会接收某个函数作为其子组件,然后在渲染函数中以 props.children 进行调用:
import React, { Component, PropTypes } from 'react'
import fetchUser from 'twitter'
class Twitter extends Component {state = {user: null,}static propTypes = {username: PropTypes.string.isRequired,}componentDidMount () {fetchUser(this.props.username).then((user) => this.setState({user}))}render () {return this.props.children(this.state.user)}
}
  • 这种模式的优势在于将父组件与子组件解耦和,父组件可以直接访问子组件的内部状态而不需要再通过 Props 传递,这样父组件能够更为方便地控制子组件展示的 UI 界面。
  • 譬如产品经理让我们将原本展示的 Badge 替换为 Profile,我们可以轻易地修改下回调函数即可:
<Twitter username='tylermcginnis33'>{(user) => user === null? <Loading />: <Profile info={user} />}
</Twitter>

8) 展示组件(Presentational component)和容器组件(Container component)之间有何不同

  • 展示组件关心组件看起来是什么。展示专门通过 props 接受数据和回调,并且几乎不会有自身的状态,但当展示组件拥有自身的状态时,通常也只关心 UI 状态而不是数据的状态。(子组件)
  • 容器组件则更关心组件是如何运作的。容器组件会为展示组件或者其它容器组件提供数据和行为(behavior),它们会调用 Flux actions,并将其作为回调提供给展示组件。容器组件经常是有状态的,因为它们是(其它组件的)数据源。(父组件)

9) 类组件(Class component)和函数式组件(Functional component)之间有何不同

  • 类组件不仅允许你使用更多额外的功能,如组件自身的状态和生命周期钩子,也能使组件直接访问 store 并维持状态
  • 当组件仅是接收 props,并将组件自身渲染到页面时,该组件就是一个 ‘无状态组件(stateless component)’,可以使用一个纯函数来创建这样的组件。这种组件也被称为哑组件(dumb components)或展示组件

10) (组件的)状态(state)和属性(props)之间有何不同

  • State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果。
  • Props(properties 的简写)则是组件的配置。props 由父组件传递给子组件,并且就子组件而言,props 是不可变的(immutable)。组件不能改变自身的 props,但是可以把其子组件的 props 放在一起(统一管理)。Props 也不仅仅是数据–回调函数也可以通过 props 传递。

11) 何为受控组件(controlled component)

  • 在 HTML 中,类似 , 和 这样的表单元素会维护自身的状态,并基于用户的输入来更新;
  • 当用户提交表单时,前面提到的元素的值将随表单一起被发送。但在 React 中会有些不同,包含表单元素的组件将会在 state 中追踪输入的值,并且每次调用回调函数时,如 onChange 会更新 state,重新渲染组件。一个输入表单元素,它的值通过 React 的这种方式来控制,这样的元素就被称为"受控元素"。

12) 何为高阶组件(higher order component)

  • 高阶组件是一个以组件为参数并返回一个新组件的函数。

    • HOC 运行你重用代码、逻辑和引导抽象。
    • 最常见的可能是 Redux 的 connect 函数。
    • 除了简单分享工具库和简单的组合,HOC 最好的方式是共享 React 组件之间的行为。如果你发现你在不同的地方写了大量代码来做同一件事时,就应该考虑将代码重构为可重用的 HOC.。

13) 为什么建议传递给 setState 的参数是一个 callback 而不是一个对象

  • 因为 this.props 和 this.state 的更新可能是异步的,不能依赖它们的值去计算下一个 state。

14) 除了在构造函数中绑定 this,还有其它方式吗

  • 你可以使用属性初始值设定项(property initializers)来正确绑定回调,create-react-app 也是默认支持的。
  • 在回调中你可以使用箭头函数,但问题是每次组件渲染时都会创建一个新的回调。

15) (在构造函数中)调用 super(props) 的目的是什么

  • 在 super() 被调用之前,子类是不能使用 this 的,在 ES2015 中,子类必须在 constructor 中调用 super()。
  • 传递 props 给 super() 的原因则是便于(在子类中)能在 constructor 访问 this.props。

16) 应该在 React 组件的何处发起 Ajax 请求

  • 在 React 组件中,应该在 componentDidMount 中发起网络请求。这个方法会在组件第一次“挂载”(被添加到 DOM)时执行,在组件的生命周期中仅会执行一次。
  • 更重要的是,你不能保证在组件挂载之前 Ajax 请求已经完成,如果是这样,也就意味着你将尝试在一个未挂载的组件上调用 setState,这将不起作用。在 componentDidMount 中发起网络请求将保证这有一个组件可以更新了。

17) 描述事件在 React 中的处理方式。

  • 为了解决跨浏览器兼容性问题,您的 React 中的事件处理程序将传递 SyntheticEvent 的实例,它是 React 的浏览器本机事件的跨浏览器包装器。
  • 这些 SyntheticEvent 与您习惯的原生事件具有相同的接口,除了它们在所有浏览器中都兼容。有趣的是,React 实际上并没有将事件附加到子节点本身。React 将使用单个事件监听器监听顶层的所有事件。这对于性能是有好处的,这也意味着在更新 DOM 时,React 不需要担心跟踪事件监听器。

18) createElement 和 cloneElement 有什么区别?

  • React.createElement():JSX 语法就是用 React.createElement()来构建 React 元素的。

    • 它接受三个参数,第一个参数可以是一个标签名。如 div、span,或者 React 组件。第二个参数为传入的属性。第三个以及之后的参数,皆作为组件的子组件。
React.createElement(type,[props],[...children]
)
  • React.cloneElement()与 React.createElement()相似,不同的是它传入的第一个参数是一个 React 元素,而不是标签名或组件。
  • 新添加的属性会并入原有的属性,传入到返回的新元素中,而就的子元素奖杯替换。
React.cloneElement(element,[props],[...children]
)

19) React 中有三种构建组件的方式

  • React.createClass()、ES6 class 和无状态函数。

20) react 组件的划分业务组件技术组件?

  • 根据组件的职责通常把组件分为 UI 组件和容器组件。
  • UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。
  • 两者通过 React-Redux 提供 connect 方法联系起来。

21) 简述 flux 思想

  • Flux 的最大特点,就是数据的"单向流动"。

    • 用户访问 View
    • View 发出用户的 Action
    • Dispatcher 收到 Action,要求 Store 进行相应的更新
    • Store 更新后,发出一个"change"事件
    • View 收到"change"事件后,更新页面

22) React 项目用过什么脚手架(本题是开放性题目)

  • create-react-app Yeoman 等

23) 了解 redux 么,说一下 redux 吧

  • redux 是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理,主要有三个核心方法,action,store,reducer。

    • 工作流程是 view 调用 store 的 dispatch 接收 action 传入 store,reducer 进行 state 操作,view 通过 store 提供的 getState 获取最新的数据;
    • flux 也是用来进行数据操作的,有四个组成部分 action,dispatch,view,store,工作流程是 view 发出一个 action,派发器接收 action,让 store 进行数据更新,更新完成以后 store 发出 change,view 接受 change 更新视图。
    • Redux 和 Flux 很像。主要区别在于 Flux 有多个可以改变应用状态的 store,在 Flux 中 dispatcher 被用来传递数据到注册的回调事件,但是在 redux 中只能定义一个可更新状态的 store,redux 把 store 和 Dispatcher 合并,结构更加简单清晰
    • 新增 state,对状态的管理更加明确,通过 redux,流程更加规范了,减少手动编码量,提高了编码效率,同时缺点时当数据更新时有时候组件不需要,但是也要重新绘制,有些影响效率。一般情况下,我们在构建多交互,多数据流的复杂项目应用时才会使用它们

24) redux 有什么缺点

  • 一个组件所需要的数据,必须由父组件传过来,而不能像 flux 中直接从 store 取。
  • 当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新 render,可能会有效率影响,或者需要写复杂的 shouldComponentUpdate 进行判断。

React 面试题汇总(一)!!!相关推荐

  1. 2021前端react面试题汇总

    2021前端react面试题汇总 React视频讲解 点击学习 全部视频:点击学习 (1)共同点 为了解决状态管理混乱,无法有效同步的问题统一维护管理应用状态; 某一状态只有一个可信数据来源(通常命名 ...

  2. 关于React面试题汇总

    1.redux中间件 中间件提供第三方插件的模式,自定义拦截 action -> reducer 的过程.变为 action -> middlewares -> reducer .这 ...

  3. react 面试题 高级_常见react面试题汇总(适合中级前端)

    转载自<原文> React 中 keys 的作用是什么? Keys 是 React 用于追踪哪些列表中元素被修改.被添加或者被移除的辅助标识. render () {return( {th ...

  4. react 面试题 高级_关于React面试题汇总

    1.redux中间件 中间件提供第三方插件的模式,自定义拦截 action -> reducer的过程.变为action -> middlewares -> reducer .这种机 ...

  5. 社招前端一面react面试题汇总

    (在构造函数中)调用 super(props) 的目的是什么 在 super() 被调用之前,子类是不能使用 this 的,在 ES2015 中,子类必须在 constructor 中调用 super ...

  6. 网易校园招聘历年经典面试题汇总:前端 岗

    这个系列计划收集几百份朋友和读者的面经,作者合集方便查看,各位有面经屯着可以联系我哦 这个系列离结束差的还特别多,会更新涵盖所有一线大厂的所有岗位,也可以关注一下. 腾讯校园招聘历年经典面试题汇总:前 ...

  7. JavaScript面试题汇总

    JavaScript 面试题汇总 1. 根据下面 ES6 构造函数的书写方式,要求写出 ES5 的 class Example { constructor(name) { this.name = na ...

  8. JavaScript 面试题汇总

    JavaScript 面试题汇总 1. 根据下面 ES6 构造函数的书写方式,要求写出 ES5 的 class Example { constructor(name) { this.name = na ...

  9. 前端面试题汇总(JavaScript面试纯干货)

    前端面试题汇总(JavaScript面试纯干货) 1 闭包 闭包就是能够读取其他函数内部变量的函数 闭包是指有权访问另⼀个函数作⽤域中变量的函数,创建闭包的最常⻅的⽅式就是在⼀个函数内创建另⼀个函数, ...

最新文章

  1. url传参参数编码的解码问题
  2. MySQL性能优化步骤
  3. 通信 / CRC 校验
  4. python视图函数是什么_python之视图函数(views.py)
  5. NSUInteger和NSInteger和int
  6. 【渝粤教育】 国家开放大学2020年春季 1039高级财务会计 参考试题
  7. Shell脚步学习指南提点
  8. python中range和arange的区别_Python——range()、xrange()和np.arange()应用说明
  9. 华为会议电脑版_大家在用什么会议产品呢? 对企业的视频会议是如何规划的?...
  10. c#调用c++dll找不到入口点,一秒搞定
  11. my makefile 自动推导
  12. Asp.net 面向接口可扩展框架之业务规则引擎扩展组件
  13. LINUX下载编译lua
  14. Keil5下载安装教程并完成注册(配图操作)
  15. echarts3 地图文字位置设置
  16. 163邮箱登录页面在哪儿?如何在手机、电脑上登陆163邮箱?
  17. 链表节点被删除时的资源释放
  18. Matlab fprintf
  19. linux 怎么彻底删除用户,linux如何完全删除用户
  20. linux unison数据同步,linux下unison双向数据实时同步

热门文章

  1. python编写字典库_Python中的字典及举例-阿里云开发者社区
  2. 京东cookie京东ck
  3. 人工智能培训班有用吗?AI培训
  4. 马斯克:你只见我谈笑间荣耀封神,却不知我曾险失所有
  5. Linux下svn报错:Can‘t create temporary file from template ‘/tmp/svn-XXXXXX‘: Permission denied
  6. java验证字符是否为字母_Java程序检查字符是否为字母
  7. 米斯特web安全培训第一期课程目录
  8. mask-image实现聚光灯效果
  9. php里面的箭头怎么打出来,PHP打印左右箭头图案的实现方法(代码示例)
  10. linux ctrl r 搜索,linux下用ctrl+r快速搜索history命令