以下是一些React中经典的知识点:
什么是React?它有哪些特点和优势?
React是一个由Facebook开发的UI框架,用于构建单页面应用程序。它的特点和优势包括:
- 组件化:React的应用程序主要由多个组件组成,每个组件都封装了自己的逻辑和状态,使得代码结构更加清晰。
- 虚拟DOM:React使用虚拟DOM来提高渲染效率和性能,尽量减少真实DOM的更新次数,从而提升用户体验。
- 数据驱动:React采用数据驱动的方式进行UI更新,当数据发生变化时,它会自动重新渲染组件,而无需手动操作。
- 与其他框架搭配使用:React可以与其他框架(如Redux、Angular)进行搭配使用,且不影响原来的架构。
更多精彩内容,请微信搜索“前端爱好者
“, 戳我 查看 。‘
React中的三种组件类型分别是什么?
React中的三种组件类型分别是:
- Function Component
- Class Component
- Pure Component
Function Component是一种纯函数组件,接收props并返回JSX元素。它的优点是简单易用、性能高效,适用于无状态数据(如展示类组件)。
Class Component是一种基于类的组件,通过继承React.Component类来创建。它可以包含状态、生命周期方法和事件处理器,适用于具有复杂逻辑和交互的组件。
Pure Component 是一种基于Class Component的优化版本,继承React.PureComponent类。它内部实现了shouldComponentUpdate方法,当组件的props和state没有发生变化时,不会重新渲染组件,从而提高性能。
什么是JSX?它与HTML的区别是什么?
JSX是一种JavaScript语法扩展,用于描述UI的结构和样式。它与HTML的区别在于:
- 属性名称采用驼峰命名法,如className、htmlFor等。
- JSX允许嵌套JavaScript表达式,以花括号{}包裹,而HTML则不支持。
- JSX中的标签名可以是自定义组件的名称,而HTML只能使用原生标签。
- JSX中需要使用自闭合标签,如
<input />
,而HTML中部分标签可以省略自闭合符号。
什么是Virtual DOM?它有什么作用?
Virtual DOM 是 React 的一个重要概念,它是一个 JavaScript 对象,它存储着对真实 DOM 树的一个虚拟表示。因为操作真实 DOM 树非常耗费性能,所以 React 将操作虚拟 DOM 树转化为正常的 JavaScript 操作,一旦完成所有操作后,再统一更新真实 DOM 树,从而提高了应用程序的性能。
Virtual DOM的作用在于:
- 提高页面渲染速度:虚拟DOM可以减少页面的重绘和回流,从而提高渲染效率。
- 简化代码结构:通过对DOM进行抽象描述,使得代码结构更加清晰、易于维护和扩展。
- 实现跨平台:虚拟DOM是一个平台无关的API,可以在多种环境中使用,如浏览器、移动端、服务器等。
虚拟 DOM 的解析过程
首先对将要插入到文档中的 DOM 树结构进行分析,使用 js 对象将其表示出来,比如一个元素对象,包含 TagName、props 和 Children这些属性。然后将这个 js 对象树给保存下来,最后再将 DOM 片段插入到文档中。
当页面的状态发生改变,需要对页面的 DOM 的结构进行调整的时候,首先根据变更的状态,重新构建起一棵对象树,然后将这棵新的对象树和旧的对象树进行比较,记录下两棵树的的差异。
最后将记录的有差异的地方应用到真正的 DOM 树中去,这样视图就更新了。
DIFF 算法的原理
在新老虚拟DOM 对比时:
首先,对比节点本身,判断是否为同一节点
- 如果不为相同节点,则删除该节点重新创建节点进行替换
- 如果为相同节点,进行patchVnode,判断如何对该节点的子节点进行处理,先判断一方有子节点一方没有子节点的情况(如果新的
children 没有子节点,将旧的子节点移除)
比较如果都有子节点,则进行updateChildren,判断如何对这些新老节点的子节点进行操作(diff 核心)。匹配时,找到相同的子节点,递归比较子节点
在 diff 中,只对同层的子节点进行比较,放弃跨级的节点比较,使得时间复杂从O(n3)降低值O(n),也就是说,只有当新旧children都为多个子节点时才需要用核心的Diff 算法进行同层级比较。
React中什么是props和state?它们之间有什么区别?
- Props(属性)是从父组件传递到子组件的数据,用于控制组件的行为和显示。在组件内部,Props是只读的,不能直接修改。
- State(状态)是组件的内部状态,用于存储组件数据和控制其渲染。它可以在组件内通过this.state访问,并且可以通过setState方法来更新。
区别:
- props是从上层组件传递下来的,而state是组件本身的状态;
- props是只读的,不能在组件内部直接修改,而state可以通过setState方法进行修改。
什么是生命周期方法?有哪些生命周期方法?
生命周期方法是React中用于控制组件生命周期的方法,它共分为三个阶段:挂载阶段、更新阶段和卸载阶段。
常见的生命周期方法有:
- constructor:组件创建时调用,用于初始化组件状态并绑定事件处理器。
- render:用于将组件渲染到页面上,必须返回JSX元素。
- componentDidMount:组件挂载后调用,用于进行异步操作或操作DOM等。
- shouldComponentUpdate:在组件更新前调用,用于判断是否需要重新渲染组件,返回值为布尔类型,若为false则停止组件更新。
- componentDidUpdate:组件更新后调用,用于进行一些必要的DOM操作等。
- componentWillUnmount:组件卸载前调用,用于清理组件相关的资源。
React中如何进行事件处理?
React中可以通过使用事件属性(如onClick、onMouseOver等)来绑定事件处理器,也可以在构造函数中手动绑定事件处理器。
此外,还可以通过箭头函数绑定this,避免this指向问题。
示例代码:
class Example extends React.Component {
handleClick = () => {
// 处理事件
}
render() {
return (
<button onClick={this.handleClick}>点我</button>
)
}
}
React 的事件和普通的 HTML 事件有什么不同?
区别:
-
对于事件名称命名方式,原生事件为全小写,react 事件采用小驼峰;
-
对于事件函数处理语法,原生事件为字符串,react 事件为函数;
react 事件不能采用 return false 的方式来阻止浏览器的默认行为,而必须要地明确地调用preventDefault()来阻止默认行为。
合成事件是 react 模拟原生 DOM 事件所有能力的一个事件对象,其优点如下:
- 兼容所有浏览器,更好的跨平台;
- 将事件统一存放在一个数组,避免频繁的新增与删除(垃圾回收)。
- 方便 react 统一管理和事务机制。
事件的执行顺序为原生事件先执行,合成事件后执行,合成事件会冒泡绑定到 document 上,所以尽量避免原生事件与合成事件混用,如果原生事件阻止冒泡,可能会导致合成事件不执行,因为需要冒泡到document 上合成事件才会执行。
React 组件中怎么做事件代理?它的原理是什么?
React 基于 Virtual DOM 实现了一个 SyntheticEvent 层(合成事件层),定义的事件处理器会接收到一个合成事件对象的实例,它符合W3C 标准,且与原生的浏览器事件拥有同样的接口,支持冒泡机制,所有的事件都自动绑定在最外层上。
在 React 底层,主要对合成事件做了两件事:
事件委派:React 会把所有的事件绑定到结构的最外层,使用统一的事件监听器,这个事件监听器上维持了一个映射来保存所有组件内部事件监听和处理函数。
自动绑定:React 组件中,每个方法的上下文都会指向该组件的实例,即自动绑定this 为当前组件。
React中怎么做到组件复用?
React中可以通过组件复用来避免代码的重复编写。常用的方法有:
- **Props传递:**通过将不同的数据传递给相同的组件,达到复用组件的目的。
- 高阶组件:高阶组件可以接受一个组件作为参数,并返回一个新的组件,通过这种方式可以对组件进行增强或者实现某个特定功能,从而避免重复编写代码。
- 继承:可以通过继承React.Component类来实现组件间的继承和复用。
React中如何实现表单控件?
React中可以通过使用内置的表单控件(如input、textarea等)来实现表单。在使用时,需要设置value属性和onChange事件处理器来实现数据的双向绑定。此外,也可以通过第三方库(如Formik)来简化表单的处理。
示例代码:
class Example extends React.Component {
state = {
text: ''
}
handleChange = (e) => {
this.setState({
text: e.target.value
});
}
handleSubmit = (e) => {
e.preventDefault();
// 处理表单提交
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.text} onChange={this.handleChange} />
<button type="submit">提交</button>
</form>
)
}
}