阅读收益:把官方文档里散落在各章节的小技巧,串成一条“开发→重构→优化→沉淀”的完整工作流;拿到需求 5 分钟就能画出代码草图,30 分钟写完组件,上线后还能睡个安稳觉。

1. 先想清楚:React 到底在解决什么问题?

  • UI = f(state):状态驱动视图,这是 React 的基石。
  • 组件化 = 把 f 拆成可复用的小函数:拆得够小,才能“只改一点、不动全身”。
  • 数据流 = 单向:数据永远从父→子,调试时只要“顺藤摸瓜”。

带着这三句话读下文,所有技巧都有统一的“为什么”。

2. 开发阶段:把需求拆成“三块两接口”

拆分维度 产出
视图块 无状态组件(展示)
状态块 有状态组件 / Hooks
副作用块 useEffect / 事件监听
对外接口 props(父→子)
对内接口 回调(子→父)

小技巧:先在纸上画 3 个框,把需求词云往里扔,就能一眼看出哪些该合并、哪些该抽象。

3. 条件渲染:别再“if/else 地狱”

  1. 三元运算符:适合“非 A 即 B”
    {isEdit ? <EditForm /> : <Preview />}
    
  2. && 短路:适合“有就渲染,没有拉倒”
    {hasError && <ErrorBanner />}
    
  3. || 兜底:适合“缺省 UI”
    {list.length || <EmptyPlaceholder />}
    
  4. 提前 return:多层分支 >3 层时,直接早退最清晰
    if (loading) return <Skeleton />;
    if (error) return <Error />;
    return <List data={data} />;
    

4. 事件处理:写一次,复用 N 次

  • 解构即注释
    const handleChange = ({ target: { value, name } }) =>
      setForm(f => ({ ...f, [name]: value }));
    
  • 统一冒泡规则
    表单内部点按钮不要触发外层卡片翻转 → e.stopPropagation()
  • 合成事件池(React 17 已取消,但仍有兼容性坑)→ 记得 e.persist() 如果异步读取事件。

5. 状态管理:从 useState 到“状态机”

场景 方案 口诀
组件内部 useState / useReducer “能用局部就不用全局”
兄弟组件 状态提升 + 最小粒度 “找到最近公共父”
全局但低频 Context + useContext “读写分家”——分别导出 Provider 与 Hook
高频 & 异步 SWR / React-Query / Redux-Toolkit “缓存即状态”

性能口诀:

  • useMemo 缓存计算结果(昂贵计算、重型列表过滤)。
  • useCallback 缓存函数引用(配合 React.memo 或 deps 数组)。
  • 不要“为了优化而优化”——React 团队实测 90% 的组件无需 memo。

6. 列表渲染:key 是“身份证”,不是“数组下标”

  • key 规则:稳定、唯一、可预测。
  • 分页/无限滚动:用 data-id 做 key,不要用 index。
  • 动态排序:先 sortmap,避免 key 错位导致 DOM 复用错误。
  • 虚拟滚动:数据 >1000 行直接上 react-window,省时省力。

7. 性能优化:一张图看懂“渲染链路”

state 改变 → 调度(Scheduler)→ Diff(Reconciler)→ Commit(Renderer)
  • React.memo:阻断“父无关更新”。
  • lazy + Suspense:把首屏不需要的组件拆出去,Webpack 自动分包。
  • 时间切片startTransition 把“搜索联想”这类低优更新延后,保持输入框不卡。

8. 样式方案:四种武器,对号入座

方案 适用场景 踩坑提示
行内 style 动态颜色/位置 不支持伪类、媒体查询
CSS Modules 中台项目、类名怕冲突 避免 :global(.xxx) 泛滥
styled-components 组件库、SSR 注意“样式漂移”(hydration mismatch)
Tailwind / Uno 快速原型、团队风格统一 别把 w-213px 这类魔法数字写死

9. 测试:让重构从“心惊胆战”到“一键回滚”

  • 金字塔模型
    70% 单元测试(Jest + React Testing Library)→ 20% 集成测试(MSW 模拟接口)→ 10%E2E(Cypress / Playwright)。
  • 快照不是银弹
    只给纯展示组件做快照,业务逻辑一改就失效的快照等于噪音。
  • 可访问性测试
    jest-axe 一行断言,把 a11y 回归进 CI,比上线后被客户投诉划算。

10. 可访问性(a11y):四条命令行搞定

npm i -D eslint-plugin-jsx-a11y
# .eslintrc  extends 加 "plugin:jsx-a11y/recommended"
npm i -D @testing-library/jest-dom
# 测试里 expect(button).toBeEnabled()
  • 键盘:所有鼠标能点的元素,保证 tabIndex=0 且有 :focus 样式。
  • 屏幕阅读器:表单控件写 <label htmlFor="xxx">;动态区域加 aria-live="polite"
  • 语义化:别用 <div onClick={}> 冒充按钮,直接 <button> 省一堆 aria。

11. 模式与复用:HOC / Render Props / 自定义 Hook 怎么选?

场景 首选 例子
逻辑+状态可复用 自定义 Hook useDebounce / useLocalStorage
需要劫持生命周期 HOC withAuth(未登录跳转)
需要灵活占位 Render Props <Toggle>{on => <Modal visible={on} />}</Toggle>

统一出口:所有可复用逻辑都放到 src/hooks/src/hocs/,禁止在业务组件里“复制 30 行相似代码”。

12. 工程化最后一公里:让规范自动运行

  • Git Hooks
    lint-staged + husky:提交前自动跑 Prettier + ESLint,坏代码进不了远程。
  • Conventional Commits
    feat: 新增表格拖拽 / fix: 修复排序图标不更新,配合 standard-version 自动生成 CHANGELOG。
  • Storybook
    把通用组件写成 Story,UI Review 直接甩链接给产品,再也不用“你本地起一下我看看”。

13. 结语:代码不是写完就完,而是“让下一个人(很可能是三个月后的你)秒懂”。

把上面的步骤变成肌肉记忆,你会发现:

  • 需求变更?改 1 个文件即可。
  • 线上告警?回滚后 5 分钟定位。
  • 新人入职?读 Storybook 就能上手。

真正的“优雅”不是技巧多,而是“让复杂消失于无形”。 祝你也能写出“睡得着”的 React 应用。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐