前端面试(React框架一)

简介: React 是一个用于构建用户界面的 JavaScript 库,采用虚拟 DOM 提升渲染效率,支持组件化开发与服务端渲染,具有良好的性能优化机制和丰富的生命周期管理。

1.React框架

1. React 的优点有哪些?

Note

React 会创建一个虚拟 DOM(virtual DOM)。当一个组件中的状态改变时,React 首先会通过 "diffing" 算法来标记虚拟 DOM 中的改变,第二步是调节(reconciliation),会用 diff 的结果来更新 DOM。

  1. JSX 的引入,使得组件的代码更加可读,也更容易看懂组件的布局,或者组件之间是如何互相引用的
  2. 支持服务端渲染,可改进SEO和性能
  3. 易于测试
  4. React 只关注 View 层,所以可以和其它任何框架(如Backbone.js, Angular.js)一起使用

2. 说一下react的生命周期?

2.1 初始化阶段

  • getDefaultProps
  • 获取实例的默认属性
  • getInitialState
  • 获取每个实例的初始化状态
  • componentWillMount
  • 组件即将被装载、渲染到页面上
  • 多用于根组件中的应用程序配置
  • render
  • 组件在这里生成虚拟的DOM节点
  • componentDidMount
  • 组件真正在被装载之后
  • 在这可以完成所有没有 DOM 就不能做的所有配置,并开始获取所有你需要的数据(发送请求);如果需要设置事件监听,也可以在这完成

2.2 运行中状态

  • componentWillReceiveProps
  • 组件将要接收到属性的时候调用
  • shouldComponentUpdate
  • 是一个改善性能的地方,组件接受到新属性或者新状态的时候(可以返回false,接收数据后不更新,阻止render调用,后面的函数不会被继续执行了)
  • componentWillUpdate
  • 组件即将更新不能修改属性和状态
  • render
  • 组件重新描绘
  • componentDidUpdate
  • 组件已经更新
  • 响应 prop 或 state 的改变

2.3 销毁阶段

  • componentWillUnmount
  • 组件即将销毁
  • 在这你可以取消网络请求,或者移除所有与组件相关的事件监听器

Note

  1. react生命周期中,最适合与服务端进行数据交互的是哪个函数? componentDidMount:在这个阶段,实例和dom已经挂载完成,可以进行相关的dom操作
  2. (在构造函数中)调用 super(props) 的目的是什么
  • 在 super() 被调用之前,子类是不能使用 this 的,在 ES2015 中,子类必须在 constructor 中调用 super()。
  • 传递 props 给 super() 的原因则是让子类中能用 constructor 访问 this.props。

3. 对setState的理解?

3.1 当你调用setState的时候,发生了什么事?

  1. 将传递给 setState 的对象合并到组件的当前状态,触发所谓的调和过程(Reconciliation)
  2. 然后生成新的DOM树并和旧的DOM树使用Diff算法对比
  3. 根据对比差异对界面进行最小化重渲染

参考连接

3.2 setState第二个参数的作用

因为setState是一个异步的过程,所以说执行完setState之后不能立刻更改state里面的值。如果需要对state数据更改监听,setState提供第二个参数,就是用来监听state里面数据的更改,当数据更改完成,调用回调函数。

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

setState它是一个异步函数,他会合并多次修改,降低diff算法的比对频率。这样也会提升性能。

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

3.4 react中key的作用(扩展)

key是React中用于追踪哪些列表中元素被修改、删除或者被添加的辅助标识。在diff算法中,key用来判断该元素节点是被移动过来的还是新创建的元素,减少不必要的元素重复渲染。

4. react中组件传值

  1. 父传子(组件嵌套浅):父组件定义一个属性,子组件通过this.props接收。
  2. 子传父:父组件定义一个属性,并将一个回调函数赋值给定义的属性,然后子组件进行调用传过来的函数,并将参数传进去,在父组件的回调函数中即可获得子组件传过来的值。

5. 在constructor中绑定事件函数的this指向

把一个对象的方法赋值给一个变量会造成this的丢失,所以需要绑定this,把绑定放在构造函数中可以保证只绑定一次函数,如果放在render函数中绑定this的话每次渲染都会去绑定一次this,那样是很耗费性能的。

Note

小技巧:在构造器constructor中绑定函数的this只需要绑定一次,在一定程度上提升了性能。

6. shouldComponentUpdate(nextProps, nextState)的作用?

  1. 当父组件被重新渲染时即render函数执行时,子组件就会默认被重新渲染,但很多时候是不需要重新渲染每一个子组件的。这时就可以使用 shouldComponentUpdate 来判断是否真的需要重新渲染子组件。仅仅一个判断,就可以节约很多的消耗。
  2. 所以对于父组件发生变化而子组件不变的情况,使用shouldComponentUpdate会提升性能。
shouldComponentUpdate(nextProps, nextState) {
    if(nextProps.content === this.props.content) {
        return false;
    } else {
        return true;
    }
}
Copy

7. PureComponent的作用?

  1. PureComponent内部帮我们实现了shouldComponentUpdate的比较,其他和Component一样。但是在shouldComponentUpdate进行的是一个浅比较,看看官方文档是怎么说的。
  2. 浅比较只比较第一层的基本类型和引用类型值是否相同
  3. 如果数据结构比较复杂,那么可能会导致一些问题,要么当你知道改变的时候调用forceUpdate,要么使用immutable来包装你的state

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

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

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

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

10 受控组件和非受控组件有什么区别?

10.1 受控组件

在HTML中,标签 inputtextareaselect的值的改变通常是根据用户输入进行更新。在React中,可变状态通常保存在组件的状态属性中,并且只能使用 setState() 更新,而呈现表单的React组件也控制着在后续用户输入时该表单中发生的情况,以这种由React控制的输入表单元素而改变其值的方式,称为:“受控组件”。

10.2 不受控组件

表单数据由DOM本身处理。即不受setState()的控制,与传统的HTML表单输入相似,input输入值即显示最新值(使用 ref 从DOM获取表单值)

11. 状态(state)和属性(props)之间有何不同?

  1. State是一种数据结构,用于组件挂载时所需的默认值。State可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果。
  2. props是组件的配置。props由父组件传递给子组件,就子组件而言,props是不可变的。组件不能改变自身props,但是可以把其他子组件的props防止一起管理。
  3. props也不仅仅是数据,回调函数也可以通过props传递。

12. 客户端渲染与服务端渲染

客户端渲染即普通的React项目渲染方式。

12.1 客户端渲染流程

  1. 浏览器发送请求
  2. 服务器返回HTML
  3. 浏览器发送bundle.js请求
  4. 服务器返回bundle.js
  5. 浏览器执行bundle.js中的React代码

Attention

因为时间在往返的几次网络请求中就耽搁了,而且因为CSR返回到页面的HTML中没有内容,就只有一个root空元素,页面内容是靠js渲染出来的,爬虫在读取网页时就抓不到信息,所以SEO不友好

12.2 SSR带来的问题

  1. React代码在服务器端执行,很大的消耗了服务器的性能
  2. 首屏加载时间过长
  3. SEO 不友好

12.3 React 同构时页面加载流程

  1. 服务端运行React代码渲染出HTML
  2. 浏览器加载这个无交互的HTML代码
  3. 浏览器接收到内容展示
  4. 浏览器加载JS文件
  5. JS中React代码在浏览器中重新执行

13. 应该在 React 组件的何处发起 Ajax 请求?

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

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

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

15. 怎么阻止组件的渲染?

在组件的 render 方法中返回 null 并不会影响触发组件的生命周期方法

16. 前端路由原理

前端路由实现起来其实很简单,本质就是监听 URL 的变化,然后匹配路由规则,显示相应的页面,并且无须刷新页面。目前前端使用的路由就只有两种实现方式。

  • Hash 模式
  • History 模式

16.1 Hash 模式

www.test.com/#/ 就是 Hash URL,当 # 后面的哈希值发生变化时,可以通过 hashchange 事件来监听到 URL 的变化,从而进行跳转页面,并且无论哈希值如何变化,服务端接收到的 URL 请求永远是 www.test.com。

window.addEventListener('hashchange', () => {
  // ... 具体逻辑
})
Copy

16.2 History 模式

History 模式是 HTML5 新推出的功能,主要使用 history.pushState history.replaceState 改变 URL。

通过 History 模式改变 URL 同样不会引起页面的刷新,只会更新浏览器的历史记录。

// 新增历史记录
history.pushState(stateObject, title, URL)
// 替换当前历史记录
history.replaceState(stateObject, title, URL)
Copy

当用户做出浏览器动作时,比如点击后退按钮时会触发 popState 事件

window.addEventListener('popstate', e => {
  // e.state 就是 pushState(stateObject) 中的 stateObject
  console.log(e.state)
})
Copy

16.3 两种模式对比

  1. Hash 模式只可以更改 # 后面的内容,History 模式可以通过 API 设置任意的同源 URL
  2. History 模式可以通过 API 添加任意类型的数据到历史记录中,Hash 模式只能更改哈希值,也就是字符串
  3. Hash 模式无需后端配置,并且兼容性好。History 模式在用户手动输入地址或者刷新页面的时候会发起 URL 请求,后端需要配置 index.html 页面用于匹配不到静态资源的时候

17. class和createClass的比较

目录
相关文章
|
15天前
|
监控 安全 Unix
iOS 崩溃排查不再靠猜!这份分层捕获指南请收好
从 Mach 内核异常到 NSException,从堆栈遍历到僵尸对象检测,阿里云 RUM iOS SDK 基于 KSCrash 构建了一套完整、异步安全、生产可用的崩溃捕获体系,让每一个线上崩溃都能被精准定位。
313 48
|
人工智能 缓存 运维
探秘 AgentRun丨通过无代码创建的 Agent,如何用高代码进行更新?
AgentRun 打破 AI Agent 开发困局,无代码快速验证想法,一键转高代码实现深度定制。60 秒创建 Agent,支持多模型、工具集成与 Prompt 优化;业务增长后可平滑演进,保留配置生成高质量代码,助力从原型到生产的持续迭代。
240 31
|
7天前
|
机器学习/深度学习 人工智能 安全
构建AI智能体:八十六、大模型的指令微调与人类对齐:从知识渊博到善解人意
本文探讨了大模型从知识储备到实用助手的进化过程。首先分析了原始预训练模型存在的问题:擅长文本补全但缺乏指令理解能力,可能生成有害或无关内容。然后详细介绍了指令微调技术,通过高质量(指令-输出)数据集教会模型理解并执行翻译、总结、情感分析等任务。进一步阐述了人类对齐技术,包括基于人类反馈的强化学习(RLHF)的三个关键步骤,使模型输出不仅符合指令,更符合人类价值观。最后展示了Qwen模型微调实践,包括代码实现和效果对比。整个过程将AI从知识库转变为既强大又安全可靠的智能助手。
121 19
|
25天前
|
传感器 安全 前端开发
电路安全防线,平芯微过压过流保护芯片深度解析与应用指南
电路安全防线,平芯微过压过流保护芯片深度解析与应用指南
|
27天前
|
消息中间件 人工智能 NoSQL
AgentScope x RocketMQ:打造企业级高可靠 A2A 智能体通信基座
Apache RocketMQ 推出轻量级通信模型 LiteTopic,专为 AI 时代多智能体协作设计。它通过百万级队列支持、会话状态持久化与断点续传能力,解决传统架构中通信脆弱、状态易失等问题。结合 A2A 协议与阿里巴巴 AgentScope 框架,实现高可靠、低延迟的 Agent-to-Agent 通信,助力构建稳定、可追溯的智能体应用。现已开源并提供免费试用,加速 AI 应用落地。
282 36
AgentScope x RocketMQ:打造企业级高可靠 A2A 智能体通信基座
|
27天前
|
存储 缓存 NoSQL
阿里云 Tair 联手 SGLang 共建 HiCache,构建面向“智能体式推理”的缓存新范式
针对智能体式推理对KVCache的挑战,阿里云Tair KVCache团队联合SGLang社区推出HiCache技术,通过多级存储卸载与全局共享机制,实现缓存命中率翻倍、TTFT降低56%、QPS提升2倍,构建面向长上下文、高并发、多智能体协作的下一代推理缓存基础设施。
288 27
阿里云 Tair 联手 SGLang 共建 HiCache,构建面向“智能体式推理”的缓存新范式
|
8天前
|
弹性计算 人工智能 缓存
2026年阿里云新用户云产品优惠政策与服务器租赁价格指南
2026 年阿里云针对新用户推出差异化服务器优惠政策,覆盖轻量应用服务器、ECS 云服务器及 GPU 服务器三大品类,提供从 2 核 2G 到 8 核 32G 的多档配置,通过限时秒杀、固定低价套餐等形式降低新用户上云门槛。不同实例适配从个人开发到企业级轻量业务的多元需求,同时支持灵活的月租与年租模式,核心围绕 “低门槛入门、长期成本可控” 设计。本文结合实例特性、价格体系及适用场景,为新用户提供客观选型参考。