Primer React 项目代码风格与最佳实践指南
前言
Primer React 是一个基于 React 的 UI 组件库,它遵循一套严格的代码风格和最佳实践。本文将深入解析这些规范,帮助开发者理解并应用这些原则来构建高质量、可维护的 React 组件。
React 开发规范
服务端渲染支持
所有组件必须支持服务端渲染(SSR),这意味着:
- 组件不能依赖浏览器特有的 API
- 需要考虑组件水合(hydration)过程
- 避免布局偏移(layout shift),实现渐进增强
关键点:组件应在没有 JavaScript 的情况下也能基本工作,JavaScript 加载后增强功能。
焦点管理策略
焦点管理应遵循以下原则:
- 优先在事件处理器中管理焦点
- 避免在副作用(effect)中管理焦点
- 确保焦点变化只由用户交互触发
原因:在 effect 中管理焦点可能导致意外的焦点移动,因为依赖项变化可能触发不必要的 effect 执行。
可控与不可控状态
组件应支持两种状态管理模式:
- 不可控模式:组件内部管理状态
- 可控模式:父组件通过 props 控制状态
实现方式:使用 useControllableState
钩子统一处理两种模式:
function Example({defaultValue, onChange, value: controlledValue}) {
const [value, setValue] = useControllableState({
value: controlledValue,
defaultValue,
onChange: ({value}) => onChange({value}),
})
}
Props 设计规范
根元素属性传递
- 所有剩余参数(...rest)应传递给根元素
- 确保
className
、data-testid
等属性能传递到 DOM
示例对比:
// 不推荐:属性传递到内部元素
<div className="outer">
<div {...rest}>{children}</div>
</div>
// 推荐:属性传递到根元素
<div {...rest}>{children}</div>
回调函数设计
回调函数参数应采用对象形式:
- 便于未来扩展新属性
- 保持一致的函数签名
- 减少破坏性变更的影响
// 不推荐:多个独立参数
onChange: (a: boolean, b: string) => void
// 推荐:单一对象参数
onChange: ({a, b}: {a: boolean; b: string}) => void
Hooks 最佳实践
Ref 处理模式
- 钩子应接受 ref 作为参数
- 避免钩子返回需要应用的 ref
原因:当多个钩子都需要 ref 时,让调用者管理 ref 更灵活:
function MyComponent() {
const ref = useRef(null)
const isHovering = useHover(ref)
const isDragging = useDrag(ref)
return <div ref={ref} />
}
回调稳定性
- 使用 ref 保存回调函数
- 避免将回调加入依赖数组
实现模式:
function useEvent(ref, eventName, callback) {
const savedCallback = useRef(callback)
useEffect(() => {
savedCallback.current = callback
}, [callback])
useEffect(() => {
const handler = (event) => savedCallback.current(event)
ref.current.addEventListener(eventName, handler)
return () => ref.current.removeEventListener(eventName, handler)
}, [ref, eventName])
}
CSS 处理规范
条件类名处理
使用 clsx
处理条件类名:
// 不推荐:手动拼接
className={`base ${active ? 'active' : ''}`}
// 推荐:使用 clsx
className={clsx('base', {active})}
状态标记方式
优先使用 data 属性而非类名表示状态:
// 不推荐:使用类名
className={clsx(classes.Example, {
[classes.primary]: variant === 'primary'
})}
// 推荐:使用 data 属性
className={classes.Example} data-variant={variant}
样式桥接方案
使用 CSS 变量连接 JS 和 CSS:
// 不推荐:内联样式
style={{color: variant === 'primary' ? 'blue' : 'red'}}
// 推荐:CSS 变量
style={{'--example-color': variant === 'primary' ? 'blue' : 'red'}}
结语
遵循 Primer React 的代码风格和最佳实践,可以确保组件库的一致性、可维护性和扩展性。这些规范涵盖了从 React 组件设计到 CSS 处理的各个方面,是构建高质量 UI 组件的基础。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考