【手撕面试题】React(高频知识点一)

        每天10道题,100天后,搞定所有前端面试的高频知识点,加油!!!在看文章的同时,希望不要直接看答案,先思考一下自己会不会,如果会,自己的答案是什么?想过之后再与答案比对,是不是会更好一点,当然如果你有比我更好的答案,欢迎评论区留言,一起探讨技术之美。

目录

面试官:简述一下什么是React(概念),特点是什么?

面试官:请说明一下什么是JSX,为什么浏览器不能读取JSX?

面试官:请你简述一下虚拟DOM的概念和机制是什么?

面试官:React类组件和函数组件之间的区别是什么?

面试官:请你简述一下React中refs的作用是什么?

面试官:请介绍一下React中的key有什么作用?

面试官:请列举一下React中常用的Hooks以及其作用

面试官:请列举React和Vue的相似性和优缺点是什么?

面试官:请你简述一下React中什么是受控组件和非控组件?

面试官:请简述一下React中的props.children和React.Children的区别?


面试官:简述一下什么是React(概念),特点是什么?

我:呃~,React是一个用于构建用户界面的JS库,由Facebook开发并在2013年首次开源,其专注于视图层,并允许开发者以声明式的方式来编写UI组件,核心思想是将UI拆分成多个可复用的组件,每个组件都包含自己的状态(state)和生命周期(lifecycle),以及一个返回React元素的render方法。其特点如下:

组件化:react是基于组件化开发的,用户界面被拆分多个独立且可复用的组件,每个组件都有自己的状态和行为,组件化使得代码结构清晰,维护性和复用性显著提高。

虚拟DOM:虚拟DOM是react自己实现的一种轻量级的文档对象模型,它通过比较前后两个状态的虚拟DOM树的差异,并只更新需要变化的部分到实际的DOM上,从而减少了DOM操作次数,提升了页面渲染性能。

单向数据流:react实现了单向数据流,即数据的流动的单向的从父组件到子组件,子组件通过props接收父组件传递的数据,而不可以直接修改父组件的数据。这种单向数据流的设计使得数据流动更加可控和易于理解,减少了数据流混乱和不可预测性。

声明式设计:开发者可以通过描述用户界面在某种状态下应该是生命样子,而不是手动操作DOM来达到期望效果。

高效生命周期管理:react提供了组件生命周期方法,允许开发者在组件不同阶段添加特定的逻辑,这些生命周期方法可以帮助开发者在组件挂载、更新、卸载等不同的阶段执行必要的操作,如数据获取、状态更新、资源清理等。

跨平台支持:react广泛支持web应用和原生移动应用开发(react native),通过react native开发者可以使用react组件模型和一部分api来构建原生移动应用,同时保持跨平台的一致性和开发效率。

面试官:请说明一下什么是JSX,为什么浏览器不能读取JSX?

我:呃~,JSX(JavaScript XML)是JS的语法扩展,它允许开发者在JS代码中编写类似xml或html的结构,它是react的核心特性之一,用于描述react组件的界面结构;在JSX中,可以通过{}大括号包裹JS表达式,这使得可以在JSX中动态地插入变量、调用函数,以及执行JS表达式。

浏览器本身只能理解和执行JavaScript、HTML 和 CSS,而JSX并不是浏览器能够直接解析和执行的内容,因为它包含了类似XML的标签语法和JS的表达式混合的结构,开发者可以通过使用Babel预处理器工具,将包含 JSX 的 JavaScript 代码转换成浏览器可以执行的普通 JavaScript即可。

面试官:请你简述一下虚拟DOM的概念和机制是什么?

我:呃~,

概念:虚拟DOM 是 React 自己实现的一种轻量级的文档对象模型(DOM)的表示,它是以 JavaScript 对象的形式来描述真实DOM树的结构和属性,真实的DOM操作通常是昂贵的,直接更新DOM可能会导致性能下降,虚拟DOM通过在内存中维护一个虚拟的DOM树来解决这个问题。React会将组件的状态(state)变化映射到虚拟DOM上,然后通过一种称为"协调(Reconciliation)"的算法,将虚拟DOM的变化高效地应用到实际的DOM上,从而最小化DOM操作次数,提高性能。

机制

1)构建虚拟DOM

每当组件的状态发生变化时,React会重新构建对应的虚拟DOM树,这个过程通过调用组件的render方法来生成新的虚拟DOM树。

2)比较虚拟DOM

React使用一种差异化算法(diffing algorithm)来比较前后两个虚拟DOM树的差异,这个算法能够高效地找出哪些部分发生了变化。

3)更新实际DOM

通过上述差异化算法找出需要更新的部分后,React将只更新这些发生变化的部分到实际的DOM中,这种精确的更新方式,减少了不必要的DOM操作,提高了页面的渲染效率。

4)批处理更新

React会将多个setState调用合并成一个更新操作,以最小化实际DOM的操作次数,这种批处理策略也有助于优化性能。

5)虚拟DOM的卸载

当组件从页面中卸载时,React会清空相应的虚拟DOM树,释放相关的内存资源,从而避免内存泄漏和资源浪费。

面试官:React类组件和函数组件之间的区别是什么?

我:呃~,React中的类组件和函数组件是两种主要的组件定义方式,它们在语法和功能上有一些明显的区别,如下:

类组件和函数组件的区别

1)定义方式

类组件:使用ES6中的class关键字来定义组件,继承自React.Component或其子类,类组件中有自己的状态和生命周期方法:

class ClassComponent extends React.Component {render() {return <div>Hello, I'm a class component.</div>;}
}

函数组件:是一种无状态函数组件,不支持状态或生命周期方法,但可以使用react hooks来引入状态和其他react特性:

function FunctionComponent() {return <div>Hello, I'm a function component.</div>;
}

2)状态管理与生命周期

类组件:可以通过this.state来管理组件的内部状态,并使用生命周期方法如componentDidMount、componentDidUpdate等来处理组件的生命周期事件。

函数组件:允许组件内部使用useState、useEffect等钩子来引入状态和处理副作用,从而实现状态管理和模拟生命周期行为。

3)性能优化

类组件:在复杂的场景下可能会因为额外的实例化和生命周期方法调用而导致性能略微下降,但在react16之后的版本,这种性能差距已经不是很显著。

函数组件:通常来说比类组件具有更好的性能,因为函数组件本身没有实例化和额外的内存开销,并且 Hooks 提供了更优雅和简洁的代码结构。

4)代码结构和可读性

类组件:在需要管理复杂状态和实现复杂逻辑时,类组件可能会更有优势,因为它们可以更结构化地管理状态和行为。

函数组件:由于没有class关键字和额外的生命周期方法,通常代码更加简洁和易于理解,适合编写简单的UI组件或者展示性组件。

随着 React Hooks 的引入,函数组件已经成为首选的组件定义方式,除非需要使用类组件特有的生命周期方法或者有复杂的状态管理需求,对于大多数场景,函数组件提供了更好的可维护性和性能优势。

面试官:请你简述一下React中refs的作用是什么?

我:呃~,在React中,ref是用来访问DOM元素或者类组件实例的一种方式。它主要有以下作用:

1)访问DOM元素:使用ref可以获取到在组件渲染后生成的DOM元素的引用,这对于需要直接操作DOM的情况非常有用,比如获取输入框的值、设置焦点、进行动画等操作:

class MyComponent extends React.Component {constructor(props) {super(props);this.myRef = React.createRef();}componentDidMount() {// 可以通过this.myRef.current访问DOM元素this.myRef.current.focus();}render() {return <input type="text" ref={this.myRef} />;}
}

2)访问组件实例:可以用来访问类组件实例,这对于调用实例方法、获取组件内部状态等操作非常有用:

class MyComponent extends React.Component {constructor(props) {super(props);this.myRef = React.createRef();}componentDidMount() {this.myRef.current.focus();// 调用类组件实例的方法this.myRef.current.doSomething();}render() {return <ChildComponent ref={this.myRef} />;}
}class ChildComponent extends React.Component {doSomething() {// 实现某些操作}render() {return <div>Child Component</div>;}
}

3)非受控组件访问:在处理表单元素的时候,ref 可以用来访问和修改非受控组件的值,例如 <input> 或 <textarea> 元素的值:

class UncontrolledForm extends React.Component {constructor(props) {super(props);this.inputRef = React.createRef();}handleSubmit = (event) => {event.preventDefault();console.log(this.inputRef.current.value);};render() {return (<form onSubmit={this.handleSubmit}><input type="text" ref={this.inputRef} /><button type="submit">Submit</button></form>);}
}

总结来说,ref提供了一种在React中访问DOM元素和类组件实例的途径,但通常情况下应该避免直接使用ref,而是优先使用React的数据流和状态管理机制来操作组件。

面试官:请介绍一下React中的key有什么作用?

我:呃~,在React中,key是用于帮助React识别列表中子元素的唯一标识符,它主要有以下作用和用途:

1)唯一标识子元素:当渲染一个由数组生成的列表时,每个子元素都需要一个唯一的 key,这有助于React检测每个元素的身份,并在列表中进行有效的更新、重新排序和删除操作。

2)识别变化:当列表中的元素发生变化时(例如添加、删除、重新排序),使用 key 来确定哪些元素已经改变,如果没有正确地指定 key,React可能会误认为某个元素发生了变化,导致不必要的重新渲染,影响性能。

3)优化列表渲染:使用适当的key帮助React优化组件的重新渲染过程,匹配当前子元素与之前渲染的子元素,以确定是否重用现有 DOM 节点或者销毁重建。

以下是一个简单的示例,展示了如何在React中使用 key:

function MyComponent({ items }) {return (<ul>{items.map(item => (<li key={item.id}>{item.name}</li>))}</ul>);
}

key 在 React 中是一个重要的属性,它帮助 React 有效地管理和更新组件树中的列表元素,提高了性能和用户体验。

面试官:请列举一下React中常用的Hooks以及其作用

我:呃~,React中常用的 Hooks 内容如下:

1)useState:用于在函数组件中添加状态管理能力,它返回一个状态变量和更新该状态变量的函数。

2)useEffect:允许在函数组件中执行副作用操作,比如数据获取、订阅管理、手动 DOM 操作等。它接收一个函数作为参数,在每次渲染后执行。可以通过 useEffect 来处理组件的生命周期操作。

3)useContext:允许函数组件订阅 React 的上下文,返回当前上下文的值,适用于在组件树中跨多层级传递数据而不必通过逐层传递 props。

4)useReducer:用于管理复杂状态和行为的 Hook,它接收一个reducer函数和初始状态,并返回当前状态和dispatch函数,适用于管理具有复杂状态转换逻辑的组件。

5)useCallback:用于缓存回调函数,依赖项发生变化时,返回的回调函数不会重新创建。

6)useMemo:用于缓存计算值而不是函数,它接收一个函数和依赖项数组,仅当依赖项变化时才重新计算值。

7)useRef:处理DOM节点引用或保存任何可变值而不触发重新渲染时非常有用。

面试官:请列举React和Vue的相似性和优缺点是什么?

我:呃~,React和Vue是当前前端开发中两个非常流行的JS框架/库,它们有一些相似性和各自的优缺点,如下:

相似性

1)组件化:都支持组件化开发,允许开发者将 UI 拆分为独立的、可复用的组件。

2)虚拟DOM:都使用虚拟DOM技术来提高性能,通过比较虚拟DOM的差异来最小化实际 DOM操作,从而提升渲染效率。

3)响应式数据流:都支持响应式数据流的概念,当数据变化时,页面自动更新。

4)单文件组件:都支持单文件组件(.vue 和 .jsx/.tsx),将组件的 HTML、CSS 和 JavaScript 代码组合在一个文件中,提高了代码的组织性和可维护性。

优缺点

react优点:提供了更大的灵活性,可以与各种库和工具链结合使用,有着庞大的生态系统和支持社区;JSX 允许将 HTML 直接嵌入到 JavaScript 中,使得组件编写更加直观和灵活。

react缺点:对于新手来说,学习 React 可能需要花费一些时间,尤其是理解其生命周期和状态管理;本身只关注 UI 层,其他的需求(如路由、状态管理)需要依赖第三方库或者选择适合的解决方案。

vue优点:API设计更加一致和友好,学习曲线相对较低,上手快;提供了完整的解决方案,包括路由、状态管理等,内部集成良好,使用更加方便。

vue缺点:灵活性相对 React 稍弱,尤其是在与其他库或工具链集成时可能需要做更多的折衷;相比于 React,Vue 的生态系统和支持库规模可能较小。

选择使用 React 还是 Vue 取决于项目的具体需求、团队的技术栈偏好以及开发者的经验和技能。React 更适合需要更大灵活性和扩展性的项目,而 Vue 则更适合那些希望快速上手、同时又希望有一整套解决方案的项目。

面试官:请你简述一下React中什么是受控组件和非控组件?

我:呃~,在React中,组件可以分为受控组件和非受控组件:

受控组件:受控组件是指其表单元素的值(如 <input>、<textarea>、<select> 等)由React的state控制的组件,具体特点包括:

1)状态由 React 管理:组件内部的状态值(如 input 的 value)由 React 的 state 控制。

2)响应式更新:任何时候,只要 state 发生变化,组件的 UI 也会相应地更新。

3)事件处理:通常配合 onChange 事件处理器来更新 state,从而更新表单元素的值。

非控组件:非控组件是指其值不受React组件state的控制,而是由DOM自身管理的表单元素,其特点是组件的值由 DOM 元素自身管理,React 不管理其值的更新,可以使用 ref 来获取表单元素的值,但不需要通过 React state 来更新或管理输入框的值。示例代码如下:

function UncontrolledInput() {const inputRef = React.useRef(null);const handleSubmit = (event) => {alert('A name was submitted: ' + inputRef.current.value);event.preventDefault();}return (<form onSubmit={handleSubmit}><label>Name:<input type="text" ref={inputRef} /></label><input type="submit" value="Submit" /></form>);
}

受控组件适合需要精确控制和处理表单数据流的场景,如实时验证或复杂表单逻辑;非控组件适合简单的表单场景,或者需要与第三方库或原生 DOM 集成的情况,通常情况下,推荐使用受控组件,因为它使得数据流更加清晰和可控,有助于避免直接操作 DOM 和增加代码复杂度。

面试官:请简述一下React中的props.children和React.Children的区别?

我:呃~,props.children和React.Children是用于处理组件内部子元素的两种不同方式:

props.children

props.children是一个特殊的prop,用于访问组件标签的内部内容,其包含了传递给组件的所有子元素,这些子元素可以是任何 React 元素:文本、元素、组件等,当组件嵌套在 JSX 中,并且有子元素时,这些子元素会自动成为 props.children 的一部分。如下给出代码示例:

const MyComponent = (props) => {return (<div><h1>{props.title}</h1><p>{props.children}</p></div>);
};const App = () => {return (<MyComponent title="Hello"><span>This is a child element.</span></MyComponent>);
};

React.Children:是React提供的一个工具集合,用于处理props.children,React.Children 提供了一些方法来操作 props.children,如 React.Children.map、React.Children.forEach、React.Children.count 等,这些允许在不直接访问 props.children 的情况下,对子元素进行映射、迭代和处理,示例代码如下:

import React from 'react';const MyComponent = (props) => {// 使用 React.Children.map 处理 childrenconst modifiedChildren = React.Children.map(props.children, child => {return <li>{child}</li>;});return (<div><h1>{props.title}</h1><ul>{modifiedChildren}</ul></div>);
};const App = () => {return (<MyComponent title="List Example"><span>Item 1</span><span>Item 2</span></MyComponent>);
};

总结

1)props.children是直接访问组件的子元素,通常用于简单的情况。

2)React.Children提供了更多的方法来处理和操作props.children,使其更加灵活和功能强大,适合处理复杂的子元素结构和逻辑。

在实际开发中,根据需要选择合适的方法来处理组件的子元素,通常情况下,使用 React.Children 提供的方法能够更好地管理和操作组件的子元素。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/367632.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux下Java11无jre文件夹的问题

项目升级需要更高级的Java版本&#xff0c;于是下载了jdk-11.0.22_linux-x64_bin.tar.gz&#xff0c;解压后jdk-11.0.22下没有jre&#xff0c;导致eclipse下“build path”无法加载jre。 Java11以上版本不在提供jre&#xff0c;Java11安装后&#xff0c;需要如下处理&#xff1…

可充电纽扣电池ML2032充电电路设计

如图&#xff0c;可充电纽扣电池ML2032充电电路设计。 图中二极管是为了防止电流倒灌&#xff0c; 电阻分压出3.66v&#xff0c;再减掉二极管压降&#xff08;约0.4v)得3.26V&#xff0c;加在电池正负极充电。 随着电池电量的积累&#xff0c;充电电流逐步减小&#xff0c;极限…

探索迁移学习:通过实例深入理解机器学习的强大方法

探索迁移学习&#xff1a;通过实例深入理解机器学习的强大方法 &#x1f341;1. 迁移学习的概念&#x1f341;2. 迁移学习的应用领域&#x1f341;2.1 计算机视觉&#x1f341;2.2 自然语言处理&#xff08;NLP&#xff09;&#x1f341;2.3 医学图像分析&#x1f341;2.4 语音…

新手教学系列——慎用Flask-SQLAlchemy慢日志记录

在使用 Flask-SQLAlchemy 开发应用时,了解和避免潜在的问题是非常重要的。特别是在常驻进程和循环执行任务的场景下,慢查询记录功能(SQLALCHEMYRECORDQUERIES)可能会引发严重的内存泄漏问题。本文将详细介绍这个问题,并提供解决方案,帮助你在开发过程中避免掉入这些陷阱。…

Java开源ERP系统Axelor汉化方法初探

Axelor简介 汉化过程介绍 定义语言和本地化 导出多语言记录 导入翻译 验证翻译 调整翻译 Axelor简介 2024年6月份Axelor ERP发布了8.1版本&#xff0c;适配JDK11及PostgreSQL12及以上版本&#xff08;7及以前版本适配JDK8及PostgreSQL10&#xff09;数据库。v8版本较之前…

Oracle - 数据库打补丁实践

原文&#xff1a;https://www.cnblogs.com/ddzj01/p/12097467.html 一、概述 本文将介绍如何给oracle数据库打最新补丁&#xff0c;数据库版本为11.2.0.4单实例&#xff0c;操作系统为redhat6.5 二、下载相关升级包 1. 登录MOS&#xff0c;查阅(ID 2118136.2)&#xff0c;下载…

TDD测试驱动开发

为什么需要TDD&#xff1f; 传统开发方式&#xff0c;带来大量的低质量代码&#xff0c;而代码质量带来的问题&#xff1a; 1.在缺陷的泥潭中挣扎 开发长时间投入在缺陷的修复中&#xff0c;修复完依赖测试做长时间的回归测试 2.维护困难&#xff0c;开发缓慢 比如重复代码&am…

Stm32的DMA的学习

一&#xff0c;介绍 二&#xff0c;DMA框图 三&#xff0c;DMA通道 四&#xff0c;相关HAL库函数 五&#xff0c;配置DMA 六&#xff0c;Stm32CubeMX配置 【13.1】减少CPU传输负载 DMA直接存储器访问—Kevin带你读《STM32Cube高效开发教程基础篇》_哔哩哔哩_bilibili

sideloadly 苹果自签和sidestore手机续签ipa记录

sideloadly 地址&#xff1a;https://sideloadly.io/#download 直接安装对应系统软件&#xff0c;然后吧ipa 拖到里面续签&#xff0c;缺点每7天需要电脑续签 如果续签保留数据需要对应的位置开启 enable file sharing 勾选 和 bundle id 修改 注意的地方需要电脑和手机appi…

echarts-wordcloud:打造个性化词云库

前言 在当今信息爆炸的时代&#xff0c;如何从海量的文本数据中提取有用的信息成为了一项重要的任务。词云作为一种直观、易于理解的数据可视化方式&#xff0c;被广泛应用于文本分析和可视化领域。本文将介绍一种基于 echarts-wordcloud 实现的词云库&#xff0c;通过其丰富的…

06-java基础——集合的复习

集合的体系结构 集合主要分为两类&#xff1a; 单列集合双列集合 一、单列集合 list系列集合&#xff1a;添加的元素是有序、可重复、有索引的。 有序&#xff1a;指的是存和取的顺序是一致的 set系列集合&#xff1a;添加的元素是无序、不可重复、无索引的。 collection&…

Python爬虫实战案例——王者荣耀皮肤抓取

大家好&#xff0c;我是你们的老朋友——南枫&#xff0c;今天我们一起来学习一下该如何抓取大家经常玩的游戏——王者荣耀里面的所有英雄的皮肤。 老规矩&#xff0c;直接上代码&#xff1a; 导入我们需要使用到的&#xff0c;也是唯一用到的库&#xff1a; 我们要抓取皮肤其…

统计信号处理基础 习题解答11-11

题目 考虑矢量MAP估计量 证明这个估计量对于代价函数 使贝叶斯风险最小。其中&#xff1a;, &#xff0c;且. 解答 贝叶斯风险函数&#xff1a; 基于概率密度的非负特性&#xff0c;上述对积分要求最小&#xff0c;那就需要内层积分达到最小。令内层积分为&#xff1a; 上述积…

【SkiaSharp绘图12】SKCanvas方法详解(一)清空、裁切区域设置、连接矩阵、注释、弧与扇形、图集、九宫格绘图、圆

文章目录 SKCanvas 方法Clear 清空ClipPath/ClipRect/ClipRegion/ClipRoundRect 设置裁切区域Concat 连接矩阵DrawAnnotation绘制注释DrawArc绘制椭圆弧、扇形DrawAtlas绘制图集(一个图像、多个区域、多个缩放、一次绘制&#xff09;DrawBitmap绘制图像DrawBitmapNinePatch九宫…

停车场车牌识别计费系统,用Python如何实现?

关注星标&#xff0c;每天学习Python新技能 前段时间练习过的一个小项目&#xff0c;今天再看看&#xff0c;记录一下~ 项目结构 说明&#xff1a; datefile文件夹&#xff1a;保存车辆信息表的xlsx文件 file文件夹&#xff1a;保存图片文件夹。ic_launcher.jpg是窗体的右上角…

vector模拟实现【C++】

文章目录 全部的实现代码放在了文章末尾准备工作包含头文件定义命名空间和类类的成员变量 迭代器迭代器获取函数 构造函数默认构造使用n个值构造迭代器区间构造解决迭代器区间构造和用n个值构造的冲突拷贝构造 析构函数swap【交换函数】赋值运算符重载emptysize和capacityopera…

字符串知识点

API API和API帮助文档 API:目前是JDK中提供的各种功能的Java类。 这些类将底层的实现封装了起来&#xff0c;我们不需要关心这些类是如何实现的&#xff0c;只需要学习这些类如何使用即可。 API帮助文档&#xff1a;帮助开发人员更好的使用API和查询API的一个工具。 String概…

【Linux】线程封装与互斥(万字)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 C多线程的用法 对原生线程进行一次封装 理解pthread线程 Linux线程互斥 进程线程间的互斥相关背景概念 互斥量mutex 操作共享变量会有问题的售票…

eventloop 事件循环机制 (猜答案)

// eventloop 事件循环机制// console.log(555);setTimeout(() > {console.log(666);})let p new Promise((resolve,reject)>{// 同步执行console.log(111);resolve();});// promise 的回调函数是异步的微任务p.then(v > {console.log(222);}, r > {console.log(r…

解决ps暂存盘已满的问题

点击编辑->首选项->暂存盘 ps默认暂存盘使用的是c盘&#xff0c;我们改成d盘即可 然后重启ps