React 前端面试全攻略:基础概念、组件、Hooks 等热门考点详解
一、基础概念
- 什么是 React? - React 是用于构建用户界面的 JavaScript 库。
- 基于组件化、声明式编程等特点,采用组件化开发方式,代码可维护和可复用性高。
- 使用虚拟 DOM 提高性能,支持服务器端渲染和移动端开发。
 
- 对 JSX 的理解? - JSX 是 React 中特有的语法扩展,允许在 JavaScript 代码中编写类似 HTML 的标记。
- 实际上会被转换为 JavaScript 函数调用,最终创建 React 元素,能方便地将界面和逻辑紧密结合。
 
- 虚拟 DOM 的概念及优势 - 虚拟 DOM 是真实 DOM 的内存表示,是一个 JavaScript 对象。
- 优势包括提高性能(通过 diff 算法找出最小差异进行更新,减少对真实 DOM 的操作)、跨平台(方便在不同环境中使用)等。
 
二、组件类
- 类组件和函数组件的区别? - 语法上,类组件需要继承 React.Component并定义render方法,而函数组件是一个纯函数接收props并返回 React 元素。
- 状态管理方面,类组件可以使用 setState管理内部状态,函数组件在 React 16.8 之前是无状态的,但之后可以使用useState等 Hooks 管理状态。
- 生命周期方面,类组件有完整的生命周期钩子,函数组件在早期没有,但可以使用 useEffect等模拟部分生命周期。
 
- 语法上,类组件需要继承 
- PureComponent 和普通 Component 的区别? - PureComponent会对- props和- state进行浅层比较,如果属性值相同则不会触发重新渲染,而普通- Component需要手动实现- shouldComponentUpdate来进行性能优化判断。
- 但 PureComponent对于复杂数据类型的比较可能存在问题,因为只是浅层比较。
 
三、状态管理类
- React 中 state 和 props 的区别? - props是父组件传递给子组件的数据,是只读的,用于组件之间的数据传递。
- state是组件内部的状态,用于管理组件自身的数据,可以在组件内部进行修改,并且状态的改变会触发组件的重新渲染。
 
- 为什么不能直接修改 React 的 state? - 直接修改 state不会触发组件的重新渲染,无法正确更新界面。
- 必须使用 setState方法来更新state,setState通过队列机制来合并和更新状态,保证数据的一致性和正确的渲染。
 
- 直接修改 
四、组件通信类
- React 中组件间通信的方式有哪些? - 父子组件通信:父组件通过 props向子组件传递数据,子组件通过props中的回调函数向父组件传递数据。
- 兄弟组件通信:可以通过共同的父组件作为中间件,在父组件中定义状态和方法,让兄弟组件通过父组件进行数据传递;也可以使用状态管理库(如 Redux 或 Context API)进行全局状态管理,实现兄弟组件之间的通信。
 
- 父子组件通信:父组件通过 
- 如何在 React 中实现跨级组件通信? - 使用 Context API 可以实现跨级组件通信,创建一个 Context对象,在父组件中提供数据,子组件中通过Context.Consumer或useContextHook 来获取数据。
 
- 使用 Context API 可以实现跨级组件通信,创建一个 
五、生命周期类
- React 16.8+ 的生命周期函数有哪些阶段及各阶段的主要方法? - 挂载阶段:constructor(初始化 state 和绑定方法)、getDerivedStateFromProps(根据新的props更新state)、render(渲染组件)、componentDidMount(获取 DOM 节点、发送网络请求等操作)。
- 更新阶段:getDerivedStateFromProps、shouldComponentUpdate(判断是否需要重新渲染组件)、render、getSnapshotBeforeUpdate(在更新前获取一些数据)、componentDidUpdate(组件更新后执行的操作)。
- 卸载阶段:componentWillUnmount(清理定时器、取消网络请求等资源释放操作)。
 
- 挂载阶段:
- React 的异步请求应该放在哪个生命周期中? - 官方推荐在 componentDidMount中进行异步请求,因为componentWillMount在 React 17 之后会被废弃,并且在该生命周期中请求可能会导致服务器渲染时请求两次以及在 React Fiber 重写后可能多次调用等问题。
 
- 官方推荐在 
六、性能优化类
- 如何提高 React 应用的性能? - 减少计算量(如使用 key属性优化列表渲染、合并多个state等)。
- 利用缓存(使用 useMemo和useCallback避免不必要的重新计算和渲染)。
- 精确重新计算的范围(只传递子组件需要的 props、实现优先级更新等)。
- 懒加载(使用 React.lazy和webpack的动态导入)。
- 懒渲染(判断组件是否在可视区域内进行渲染)等。
 
- 减少计算量(如使用 
七、Hooks 类
- React Hooks 的使用规则及为什么有这些规则? - 规则包括只能在函数组件的顶级调用 Hooks,不能在循环、条件判断或嵌套函数中调用。
- 这是因为 Hooks 的实现基于数组,不按规则调用会导致数组取值错位,执行错误的 Hook。
 
- useEffect 和 componentDidMount、componentDidUpdate、componentWillUnmount的关系?- useEffect结合不同的依赖项数组参数可以模拟- componentDidMount(依赖项数组为空)、- componentDidUpdate(依赖项数组为指定的状态)、- componentWillUnmount(在- useEffect的返回函数中执行清理操作)。
 
八、路由类(如果使用了 React Router)
- React Router 的实现原理? - 基于浏览器的路由机制(如 hash路由和H5 history路由),通过监听 URL 的变化,根据配置的路由路径匹配对应的组件并进行渲染,同时维护历史记录等。
 
- 基于浏览器的路由机制(如 
- 如何配置 React Router 实现路由切换、重定向、获取 URL 的参数和历史对象? - 配置路由切换需要使用 <Route>组件定义路由路径和对应的组件,使用<Switch>组件进行路由匹配,使用<Link>或useHistory等进行导航和路由操作。
- 重定向可以使用 <Redirect>组件。
- 获取 URL 的参数可以通过 props.match.params(动态路由参数)、props.location.search(查询参数)等方式。
- 获取历史对象可以使用 useHistoryHook 或this.props.history(在类组件中)。
 
- 配置路由切换需要使用 
九、高阶组件类
- 什么是高阶组件?有什么作用和应用场景? - 高阶组件是一个函数,接收一个组件作为参数并返回一个新的组件。
- 作用是复用组件逻辑、增强组件功能等。
- 应用场景如对组件进行权限验证、日志记录、数据处理等操作。
 
十、Refs 类
- Refs 在 React 中的作用是什么?如何使用? - Refs 提供了一种访问 render方法中创建的 DOM 节点或 React 元素的方法。
- 可以通过在组件上添加 ref属性,属性值为回调函数接收底层 DOM 元素或组件实例,或者使用字符串形式的ref在组件实例的refs属性中存储对 DOM 元素的引用。
- 常用于获取 DOM 元素的信息、操作 DOM 元素、在表单元素中获取用户输入的值等。
 
- Refs 提供了一种访问 
十一、总结
本文全面总结了 React 前端面试常见问题,涵盖基础概念、组件、状态管理、组件通信、生命周期、性能优化、Hooks、路由、高阶组件和 Refs 等方面。在面试中,除掌握这些知识点外,还需能够实际应用来解决问题。
在 React 的世界里,每一次挑战都是成长的机遇。勇敢面对面试,展现你的实力,相信自己一定能在 React 前端的道路上绽放光彩!
