React 面试精粹:这些高频知识点你掌握了吗?
1. React 的生命周期有哪些?
React 组件的生命周期大致可以分为以下三个阶段:挂载阶段、更新阶段 和 卸载阶段。每个阶段都有对应的生命周期方法。
1. 挂载阶段(Mounting)
挂载阶段是指组件被创建并插入到 DOM 中的过程。在这个阶段会触发以下方法:
- constructor:初始化状态或绑定方法,是组件实例创建的第一个方法。
- static getDerivedStateFromProps(nextProps, prevState):在组件挂载或更新时调用,用于在渲染前更新状态。
- render:唯一必需的方法,返回组件的 JSX,描述组件的 UI。
- componentDidMount:组件挂载后调用,常用于进行异步请求或 DOM 操作。
2. 更新阶段(Updating)
更新阶段发生在组件的状态或属性发生变化时。React 会重新渲染组件并触发以下方法:
- static getDerivedStateFromProps(nextProps, prevState):每次更新前调用,用于根据 props 更新状态。
- shouldComponentUpdate(nextProps, nextState):用来判断是否允许更新,返回
true
允许更新,返回false
阻止更新。 - render:重新渲染组件,生成新的 DOM。
- getSnapshotBeforeUpdate(prevProps, prevState):在 DOM 更新前调用,返回的值会传递给
componentDidUpdate(prevProps, prevState, snapshot)
。 - componentDidUpdate(prevProps, prevState, snapshot):组件更新后调用,通常用于操作更新后的 DOM 或发起异步请求。
3. 卸载阶段(Unmounting)
卸载阶段是指组件即将被从 DOM 中移除的过程。在这个阶段只会调用一个方法:
- componentWillUnmount:组件卸载前调用,用于清理定时器或取消网络请求等。
4. 错误处理阶段(Error Handling)
React 16 引入了新的错误处理方法,用于捕获组件中的错误。
- componentDidCatch:在子组件出现错误时调用,接收
error
和info
参数,可以用于记录错误信息或展示降级 UI。 - static re'a:用来更新组件状态以响应渲染错误,常用于实现错误边界。
React 生命周期方法一览表
阶段 | 生命周期方法 | 描述 |
---|---|---|
挂载 | constructor | 初始化状态和方法绑定。 |
static getDerivedStateFromProps(nextProps, prevState) | 在挂载前或更新前调用,用于根据 props 初始化或更新状态。 | |
render | 必需方法,返回 JSX 描述组件 UI。 | |
componentDidMount | 组件挂载后调用,适合进行异步请求或 DOM 操作。 | |
更新 | static getDerivedStateFromProps(nextProps, prevState) | 在更新前调用,根据新的 props 更新状态。 |
shouldComponentUpdate(nextProps, nextState) | 控制是否允许更新,返回 true 继续更新,返回 false 阻止更新。 | |
render | 重新渲染组件生成新的 DOM。 | |
getSnapshotBeforeUpdate(prevProps, prevState) | DOM 更新前调用,返回值传递给 componentDidUpdate(prevProps, prevState, snapshot) 。 | |
componentDidUpdate(prevProps, prevState, snapshot) | 组件更新后调用,用于操作更新后的 DOM。 | |
卸载 | componentWillUnmount | 组件卸载前调用,适合清理定时器或取消异步请求。 |
错误处理 | componentDidCatch | 捕获子组件错误,用于记录错误或展示降级 UI。 |
static getDerivedStateFromError | 在渲染时遇到错误时调用,更新组件状态以展示备用 UI。 |
React 16+ 新的生命周期方法
React 16 引入了 static getDerivedStateFromProps(nextProps, prevState)
和 getSnapshotBeforeUpdate(prevProps, prevState)
,并逐步弃用了 componentWillMount
、componentWillReceiveProps
和 componentWillUpdate
。旧方法依然可用,但在使用时会有提示。
2. 什么是 JSX?
JSX(JavaScript XML)是一种 React 引入的语法扩展,允许在 JavaScript 代码中直接编写类似 HTML 的语法,用于描述组件的 UI 结构。它在浏览器运行之前会被编译为标准 JavaScript(如 React.createElement
调用),从而创建虚拟 DOM 节点。
JSX 的特性
- 类似 HTML 的语法:JSX 的语法接近 HTML,让代码更直观地描述 UI 结构,便于阅读和维护。
- JavaScript 表达式支持:可以在 JSX 中使用大括号
{}
包裹 JavaScript 表达式,例如变量、条件表达式、函数调用等,增强了组件的灵活性。 - 编译为 JavaScript:JSX 语法本质上是对 JavaScript 的扩展。通过 Babel 等工具编译后,JSX 会被转换为
React.createElement
形式的 JavaScript 代码。
JSX 的语法规则
- 顶层元素:JSX 语法必须有一个唯一的顶层父元素,通常使用
或
。 - 属性名和 className:在 JSX 中,
class
属性需要写成className
,因为class
是 JavaScript 的保留字;事件名等属性遵循 camelCase 格式,如onClick
、onChange
等。 - 表达式使用:在 JSX 中可以通过
{}
包裹 JavaScript 表达式,比如动态数据或函数调用。 - 注释:在 JSX 中使用
{/* 注释内容 */}
进行注释。
3. React 组件通信如何实现?
在 React 中,组件之间的通信方式主要根据组件的层级关系决定。以下是几种常见的组件通信方式:
1. 父子组件通信
父组件向子组件传递数据,或通过子组件调用父组件的方法。
- 通过 props 传递数据:父组件可以将数据通过 props 传递给子组件,子组件通过
props
接收。 - 回调函数传递事件:父组件可以将一个回调函数作为 props 传递给子组件,子组件调用该回调函数并传入参数,父组件接收数据。
2. 兄弟组件通信
兄弟组件之间通常没有直接关系,数据传递需要通过共同的父组件或全局状态管理工具。
- 状态提升:将状态提升至共同的父组件,通过 props 将状态和更新函数传递给兄弟组件,兄弟组件间通过共享父组件的状态实现通信。
- 状态管理库(如 Context 或 Redux):将共享状态存储在全局状态中,兄弟组件可以通过订阅状态来实现通信。
3. 跨层级组件通信
对于层级较深的组件通信,可以通过 Context API 或全局状态管理工具(如 Redux、MobX、Recoil 等)。
- Context API:创建 Context,在顶层组件中使用
Provider
提供状态,然后在深层子组件中使用useContext
消费数据。 - 全局状态管理库:在大型应用中共享复杂全局状态,使用 Redux、MobX 等实现跨层级状态管理和通信。
4. 发布订阅模式
在较复杂的应用中,发布订阅模式(Pub/Sub)用于实现松耦合的组件通信。
- 事件总线(Event Bus):在项目中创建一个中央事件总线,不同组件可以通过事件名发布和订阅消息,实现组件间通信。
5. URL 和路由参数
在基于路由的 React 应用中,可以通过 URL 和路由参数在不同页面组件间传递数据。
- URL 参数:通过路由中的参数传递数据,组件可以通过
useParams
等钩子函数获取。 - 查询字符串:在 URL 中添加查询字符串,通过
location.search
或专用的库解析获取数据。
总结
- 父子组件通信:通过 props 和回调函数传递数据和事件。
- 兄弟组件通信:状态提升到共同的父组件,或使用 Context、状态管理库。
- 跨层级通信:使用 Context API 或状态管理库管理全局状态。
- 发布订阅模式:使用事件总线实现松耦合通信。
- 路由参数:通过 URL 和查询字符串在不同页面组件间传递数据。
4. React 如何进行组件/逻辑复用?
在 React 中,组件和逻辑复用是提高代码复用性、可维护性和扩展性的关键方法。以下是几种常用的实现方式:
1. 高阶组件(Higher-Order Components,HOC)
高阶组件是一个函数,接受一个组件作为参数并返回一个新的组件。它用于为现有组件增加额外的功能或行为,通常用于跨多个组件的功能复用,如身份验证、日志记录、权限控制等。
- 优点:可以动态地为组件添加功能,提高复用性。
- 缺点:可能导致组件树嵌套过深,增加调试和维护的复杂度。
2. 自定义 Hook
自定义 Hook 是 React 16.8 引入的一种复用逻辑的方式,允许开发者将状态逻辑抽象成独立的函数,使其在多个组件间复用。自定义 Hook 使得组件的逻辑和状态管理更加模块化,避免了重复的代码。
- 优点:能够复用逻辑,而不需要修改组件结构;非常适合处理状态逻辑、数据获取等场景。
- 缺点:只能复用逻辑,不能复用 UI 或样式。
3. Render Props 模式
Render Props 模式是一种通过将函数作为 props 传递给组件,让父组件控制子组件渲染内容的模式。父组件通过函数传递给子组件,子组件调用该函数来控制其渲染内容,进而实现状态共享或行为复用。
- 优点:灵活控制组件的渲染,适合复杂的逻辑复用。
- 缺点:可能导致「嵌套地狱」,特别是在多层嵌套的情况下。
4. 组件组合(Composition)
组件组合是通过将多个独立的组件组合在一起,实现更复杂的组件功能。它强调将逻辑和 UI 拆分成多个小组件,然后将它们组合在一起,通过 props 或子组件来传递数据和行为。
- 优点:提高组件的可复用性和组合性,组件之间解耦,代码清晰。
- 缺点:可能需要在父组件中管理更多的状态,增加了管理的复杂度。
总结
- 高阶组件(HOC):适合复用功能逻辑,跨多个组件。
- 自定义 Hook:适用于复用状态逻辑,不涉及 UI。
- Render Props:灵活控制组件渲染内容,适合复杂的状态或行为共享。
- 组件组合:通过组合多个小组件,提升 UI 和功能的复用性。
这些方法各有优缺点,开发者可以根据需求和应用场景选择合适的方式进行组件和逻辑的复用。
5. 受控组件和非受控组件有什么区别?
在 React 中,组件的状态管理方式分为受控组件和非受控组件。两者的主要区别在于如何管理和访问表单元素的值。
1. 受控组件(Controlled Components)
受控组件是指组件的表单元素(如 、
评论记录:
未查询到任何数据!