1. 如何优化大型列表渲染性能?
-
核心方法:
- 唯一
key
属性 :通过唯一标识符(如item.id
)帮助 React 识别元素差异,减少全量更新。 - 虚拟列表技术 :使用
react-window
或react-virtualized
仅渲染可视区域元素,降低 DOM 节点数量。 - 组件缓存 :通过
React.memo
对列表项进行浅层 Props 比对,避免子组件无效渲染。 - 分页/懒加载 :结合
Intersection Observer
实现滚动加载,减少一次性渲染数据量。
- 唯一
-
代码示例:
javascriptimport { FixedSizeList as List } from 'react-window'; const Row = ({ index, style }) => <div style={style}>{data[index].name}</div>; <List height={600} itemCount={data.length} itemSize={50}>{Row}</List>;
2. 在 React 中如何实现细粒度权限控制?
-
设计模式:
- 高阶组件(HOC) :封装权限校验逻辑,拦截无权限组件渲染。
- 自定义 Hooks :如
usePermission
动态返回当前用户权限状态。 - 路由守卫:在路由配置中集成权限校验,拦截非法路径跳转。
-
示例场景:
javascriptconst withAuth = (WrappedComponent, requiredRole) => (props) => { const { userRole } = useAuth(); return userRole === requiredRole ? <WrappedComponent {...props} /> : null; };
3. 如何设计一个支持撤销/重做的表单?
-
实现方案:
- 状态快照 :使用
Immer
生成不可变状态历史记录,存储操作堆栈。 - 命令模式:封装表单操作为独立命令对象,支持回滚与重放。
- 内存优化:限制历史记录数量(如最多 50 步),避免内存泄漏。
- 状态快照 :使用
-
代码片段:
iniconst [history, setHistory] = useState([]); const handleChange = (newValue) => { setHistory(prev => [...prev.slice(-49), currentState]); setState(newValue); };
4. React 项目中如何实现多主题切换?
-
技术选型:
- CSS 变量 :通过
:root
定义主题变量,动态修改document.documentElement
属性。 - Context API :创建
ThemeContext
传递当前主题配置,触发组件级更新。 - CSS-in-JS :使用
styled-components
的ThemeProvider
实现动态样式注入。
- CSS 变量 :通过
-
性能优化:避免在渲染期间动态生成 CSS 规则,优先预定义主题类名。
5. 如何用 React 实现一个实时数据仪表盘?
-
关键点:
- WebSocket 集成 :使用
socket.io-client
建立长连接,推送实时数据。 - 数据聚合 :对高频更新数据进行节流(
lodash.throttle
),降低渲染压力。 - 图表优化 :采用 Canvas 渲染的库(如
ECharts
),避免 SVG 性能瓶颈。
- WebSocket 集成 :使用
-
防抖示例:
scssconst throttledUpdate = useMemo(() => throttle(updateChart, 500), []); socket.on('data', throttledUpdate);
6. 在 SSR 项目中如何解决客户端与服务端状态不一致问题?
-
同步策略:
- 数据脱水(Dehydration) :服务端将初始状态嵌入 HTML,客户端通过
window.__INITIAL_STATE__
获取。 - 状态合并:客户端初始化时优先使用服务端预取数据,覆盖默认空状态。
- 请求复用 :在 Next.js 中通过
getServerSideProps
保证服务端与客户端数据同源。
- 数据脱水(Dehydration) :服务端将初始状态嵌入 HTML,客户端通过
7. 如何实现一个支持拖拽排序的组件?
-
技术实现:
- 库选择 :使用
react-beautiful-dnd
处理拖拽事件与动画过渡。 - 数据持久化 :在
onDragEnd
回调中更新数据源,同步至后端或本地存储。 - 性能优化 :对拖拽项应用
will-change: transform
属性,启用 GPU 加速。
- 库选择 :使用
8. React 项目中如何管理全局弹窗/通知系统?
-
架构设计:
- Portal 挂载 :将弹窗渲染至
document.body
外的独立 DOM 节点,避免层级干扰。 - 队列机制:通过 Redux 或 Context 维护弹窗队列,按优先级顺序展示。
- 动画过渡 :集成
react-spring
实现平滑的入场/退场动画。
- Portal 挂载 :将弹窗渲染至
9. 如何设计一个可复用的表单组件库?
-
核心原则:
- 受控组件 :通过
value
+onChange
实现数据双向绑定,支持外部状态管理。 - 表单校验 :集成
react-hook-form
实现声明式校验规则,减少重复代码。 - 复合组件 :通过
React.Children.map
动态组合表单项,保持 API 简洁。
- 受控组件 :通过
10. React + TypeScript 项目中如何避免 any 类型泛滥?
-
类型策略:
- 泛型组件 :定义可复用的带类型参数组件(如
Table<T>
)。 - 工具类型 :使用
Pick
、Omit
等 Utility Types 精确约束 Props 范围。 - 第三方库扩展:通过声明合并(Declaration Merging)补充缺失类型定义。
- 泛型组件 :定义可复用的带类型参数组件(如
-
示例:
typescripttype APIResponse<T> = { data: T; error?: string }; const fetchData = async <T,>(): Promise<APIResponse<T>> => { ... };