React常见面试题与高阶面试题全解析:从基础到源码原理
一、基础面试题
1. 类组件与函数组件的区别
- 类组件:使用ES6类定义,可通过
this.state
管理状态,具有完整的生命周期方法(如componentDidMount
)。 - 函数组件:原为无状态组件,React 16.8后通过Hooks(如
useState
、useEffect
)实现状态和生命周期功能。 - 核心区别:类组件通过实例化运行,函数组件通过闭包捕获状态,Hooks更符合函数式编程思想。
2. 受控组件 vs 非受控组件
- 受控组件:表单值由React状态控制(如
value
绑定state
+onChange
更新),数据流显式可控。 - 非受控组件:通过
ref
直接操作DOM获取表单值,适用于集成非React代码的场景。
3. 组件通信方式
- 父子:父传子通过
props
,子传父通过回调函数。 - 兄弟/跨层级:使用Context API、全局状态管理(Redux)或事件总线(较少推荐)。
- 反向数据流:子组件调用父组件传递的方法更新状态。
4. React事件机制
- 合成事件:React将浏览器原生事件封装为跨浏览器兼容的对象,通过事件池复用提升性能。
- 事件委托:所有事件统一绑定到根容器,通过事件冒泡机制分发,减少内存消耗。
5. 虚拟DOM与Diff算法
- 虚拟DOM:轻量化的JS对象,描述真实DOM结构,避免直接操作DOM的性能损耗。
- Diff策略:树对比(分层比较)、列表Key优化、组件类型比对,仅更新变化部分。
二、高阶面试题
1. Hooks原理与自定义Hook
- 实现原理:Hooks通过链表结构保存状态,依赖调用顺序确保状态正确对应。
- 自定义Hook:封装通用逻辑(如数据请求),命名以
use
开头,遵循Hooks规则。
2. 高阶组件(HOC)实现与设计思想
- 定义:接收组件返回增强组件的函数,用于逻辑复用(如鉴权、日志记录)。
- 设计模式:基于函数式编程的高阶函数思想,解决类组件横切关注点问题。
const withLogger = (Component) => (props) => { console.log('Rendered:', Component.name); return <Component {...props} />;};
3. React Fiber架构原理
- 目标:解决同步渲染阻塞问题,实现可中断的异步渲染。
- 实现:将渲染任务拆分为多个Fiber节点,通过
requestIdleCallback
调度任务优先级。
4. 性能优化策略
- 组件级:
React.memo
缓存函数组件,PureComponent
浅比较props/state。 - 数据级:使用不可变数据(Immutable.js)避免深层比较。
- 代码级:动态导入(
React.lazy
+Suspense
)实现代码分割。
三、原理深入
1. 合成事件系统
- 目的:统一浏览器事件差异,实现事件池复用,提升性能。
- 过程:事件注册到根节点,触发时生成合成事件并分发给组件。
2. JSX编译原理
- 转换:通过Babel将JSX转换为
React.createElement(type, props, children)
调用。 - 结果:生成描述DOM结构的虚拟DOM对象。
四、实战编码题
1. 实现高阶组件(HOC)
const withLoading = (WrappedComponent) => { return (props) => ( props.isLoading ? <Spinner /> : <WrappedComponent {...props} /> );};
考点:逻辑复用、条件渲染。
2. 自定义Hook封装
const useFetch = (url) => { const [data, setData] = useState(null); useEffect(() => { fetch(url).then(res => res.json()).then(setData); }, [url]); return data;};
考点:副作用管理、逻辑抽象。
总结:React面试需同时掌握基础API和底层原理,结合项目经验解释优化策略,并展示对技术演进(如Hooks取代HOC)的思考。高阶问题常围绕设计模式与架构设计展开,需深入理解React哲学。