claude code 在 React 项目中的实战经验

我和 Claude Code 结对编程三个月了。不是“试用”,不是“体验”,是每天8小时在同一套 React 项目里共同工作,它写代码,我审查;我提需求,它实现。这篇文章不是什么工具介绍,也不是功能罗列,而是三个真实回合的复盘:我们怎么吵起来的、它哪里比我还像Senior、以及我为什么最终决定让它留在技术栈里。

先说结论,再说过程。

如果你期待“AI一键生成完美代码”的故事,这篇文章会让你失望。但如果你想找一个真正能帮你搬砖的AI搭档,一个会把你的烂需求怼回来、会主动补测试、会在第五轮对话还记住你项目结构的搭档,Claude Code可能是目前最接近这个定义的。

当然,它的Code Review也能把你气到想删库。

我们开始。

一、第一天:5分钟生成骨架,那一刻我真的慌了

先交代背景: 我接了一个内网数据看板的React项目。技术栈是React 18 + TypeScript + Ant Design + Zustand + React Query。需求方要求两周内上线,成员只有我一个。

如果你接过这类项目,你知道前端最大的时间黑洞不是写组件,而是搭建那套永远会有Bug的基础架构,路由守卫、权限拦截、Token刷新、请求重试、Zustand Store模块化。这些东西重要但无聊,每次写都烦。

所以我做了个实验:把这个任务完全甩给Claude Code。

我给它的第一句Prompt:

> “Create a React project with TypeScript, Ant Design, Zustand and React Query skeleton. Include: route guards based on JWT token stored in localStorage, separate menu config for admin/user roles, automatic token refresh in axios interceptor, and a global loading state in Zustand. Requirements: each module should be separated in different files, TypeScript strict mode, no any type.”

14秒后,它生成了完整的项目目录:

src/
  components/
  hooks/
  pages/
  store/
  utils/
  routes/
  services/

关键不在于目录,而在于它考虑了耦合关系。 比如auth store被routes的guard引用时,它自动在guard文件里import了正确的store路径;Token刷新逻辑放在interceptor里而非散落在各个service文件里,这是有经验的开发者才会在项目初期确定的架构决策。

我当时做了个测试:用Chrome DevTools故意制造401错误,看它写的interceptor会不会自动重试。结果token刷新成功后,原来的请求队列确实重新发送了,连isRefreshing锁都写好了。

claude code 在 React 项目中的实战经验

但我真正慌的不是速度,而是它的“业务感知”。

一般来说,AI生成的代码即使能跑,变量命名也是data1、obj、temp这种毫无语义的东西。但Claude Code生成的AdminRouteGuard和UserRouteGuard组件,不仅名字清楚,还考虑了管理员的降级逻辑,当管理员Token过期时,它不是跳登录,而是跳一个“权限已过期,是否重新验证”的中间页。

这个细节让我意识到:它不是在“生成代码”,它是在“根据一个运行中的React生态做推断”。

然而,当我以为可以提前下班的时候,真正的噩梦开始了。

二、第二回合:我们就“状态管理到底用Zustand还是Context”吵了整整40分钟

这个争论不是我挑起的,是我真的走错了路。

项目里有一个比较复杂的搜索筛选模块:用户可以在一个数据表格上方,通过6个筛选项(日期范围、部门、项目名称、状态、负责人、预算区间)组合查询。6个筛选项互相联动,比如选了某个部门,负责人下拉框只显示该部门的人;选了某个项目,预算区间自动调整上下限。

我最初的想法很简单:全部塞进Zustand Store

给Claude Code的Prompt是:

> “Create a Zustand store for search filters with these 6 fields, support mutual dependencies, debounce search input, sync with URL params so the filter state survives page refresh.”

它生成的代码大概长这样:

interface SearchFilterStore {
  dateRange: [Date, Date];
  department: string;
  projectName: string;
  status: string;
  responsiblePerson: string;
  budgetRange: [number, number];
  setDateRange: (range: [Date, Date]) => void;
  setDepartment: (dept: string) => void;
  // ...6个setter
}

这段代码能跑。但它有一个致命的React生态陷阱: 当日期范围变化时,整个Store的所有consumer都会重渲染,即使某个组件只订阅了status字段,也会因为store的引用变化而触发re-render。

我用React DevTools Profiler测了一下,单次筛选项切换导致7个订阅组件全部rerender,预算区间组件甚至在完全没有变化的情况下重渲染了

我开始跟Claude Code争论:

第一轮Prompt:

> “The current Zustand approach causes unnecessary re-renders. When I change dateRange, components subscribing only to status also re-render. Suggest a solution.”

它回了三段话,建议“split the store into multiple slices and use selectors”。

我按它说的重构,确实好了一点。但新的问题出现了:切片后依赖逻辑变复杂了。比如部门切片需要触发负责人切片的重置,这种跨切片通信在Zustand里需要手动管理订阅或者用midddleware。代码从80行膨胀到170行,维护成本暴增。

第二轮Prompt:

> “Now the cross-slice communication makes the code harder to maintain. Should I consider using React Context + useReducer instead? Compare the two approaches based on: re-render control, maintainability, and TypeScript type safety.”

Claude Code的回答让我意外,它不是简单说“用Context”,而是给了我一个决策树:

  1. 如果筛选项<3个且无联动→ Context足够,代码最简
  2. 如果筛选项3-6个且联动复杂→ Zustand + Selector + shallow equality
  3. 如果筛选项>6个或有跨页面共享需求→ Zustand + Slice + 自定义selector hooks
  4. 任何时候都不推荐在联动场景下用纯Context + useReducer:因为context value变化会导致整棵树重渲染,除非你拆10个Context,但那样代码比Zustand更恶心

它还补了一句让我惭愧的话:

> “Your current use case falls into category 2. The real problem is not Zustand vs Context, but that you're not using selectors correctly. Each component should only subscribe to the fields it actually reads.”

它说的对。我的问题不是因为Zustand,而是我把整个Store对象一把梭传给了每个组件。

我重新给它Prompt:

> “Refactor my Zustand store to use atomic selectors. Each filter field should be subscribed independently. Add shallow equality comparison. Also, extract the filter logic into a custom hook useSearchFilters that encapsulates the debounce and URL sync logic.”

这次它生成的代码,用React.memo + selector + shallow的组合拳,把重渲染从7个组件降到只有实际变化的1-2个。

claude code 在 React 项目中的实战经验

这场40分钟的争论让我学到三个原则:

  • AI会给方案,但不会替你做判断。 它不能知道你的团队有几个人、未来维护者是谁、业务变化频率,这些需要你自己决定。
  • 先花5分钟定义问题,再让AI写代码。 如果我一上来就问“怎么优化这个Store的渲染性能”,它会直接给方案;但我先让它“比较Context和Zustand的优势劣势”,它给的答案才有判断价值。
  • React的渲染优化是AI的强项。 因为它记住了全量官方文档和社区实践,它能在5秒内回顾Zustand的selector机制、React.memo的工作原理、shallow equality的陷阱,而这些我需要查半小时。

三、它最让我意外的能力:反向审查我的Prompt

做那个数据看板项目时,有一次我给它提需求,它拒绝了我。

Prompt是:

> “Add a useEffect that fetches the department list when the component mounts, and also refetch when the projectName changes. Store the department list in local state.”

Claude Code的回复:

> “I recommend reconsidering this approach. Fetching department list based on projectName change creates a dependency chain that may cause race conditions. If the user rapidly changes projects, older requests may resolve after newer ones, causing stale data display.

>

> Alternative: use React Query's queryKey to automatically manage this dependency. It includes built-in request cancellation for stale queries. Here's a revised implementation…”

一个AI在挑战我的技术方案,而且它的理由是对的。

竞态条件这事儿,坦白说我在写这个需求时完全没想起来。如果真按我的思路写,测试环境可能发现不了(因为数据加载太快),但生产环境在高并发或慢网络下迟早会出Bug。

这不是“生成代码”,这是“代码审查”。 这个行为模式更像一个Senior Developer坐在你旁边说:“这个方案我在上一个项目踩过坑,要不要换个思路?”

我把这件事扩展成一个使用习惯:每次给Claude Code提需求时,最后加一句“Are there any edge cases or potential issues with this approach?”

这句话导致了大量的“争议对话”,但也帮我避开了以下问题:

  • 内存泄漏:我写的一个useEffect订阅了window resize事件但没有cleanup函数,它直接指出来了。
  • 多余的API调用:我设计的“删除了项目后重新拉取全量列表”,它建议我用乐观更新。
  • 类型安全漏洞:我在TypeScript中用了as any来快速绕过类型报错,它在Review时直接标出“this loses type safety, suggest defining a proper interface”。

四、写单元测试:我承认,它比我强

我讨厌写测试。不是因为测试不重要,而是因为我写测试时有三个毛病:总测正向路径、忽略边界值、覆盖率到80%就觉得够了

这次数据看板项目,我试了试Claude Code的测试生成能力。给它的Prompt:

> “Generate comprehensive unit tests for this SearchFilterPanel component. Include: all state transitions, edge cases (empty values, null, undefined, very long strings), race condition scenarios, and interaction sequences (user types, clears, selects dropdown). Use Vitest + React Testing Library.”

它生成的测试文件,说实话我看完之后觉得自己写不如它:

  1. 它测试了清空日期范围后的状态回滚,这个我压根没想过要测。
  2. 它模拟了用户快速连续输入时的debounce行为,连这个都测了。
  3. 它测试了“部门切换后负责人字段是否被正确重置”,典型的联动逻辑边界检查。
  4. 它用了waitFor来验证异步状态更新的时序,很多人写测试只断言最终结果,不关心中间状态转换。

有一个测试让我印象深刻:

it('should cancel previous debounced request when new input arrives', async () => {
  const { result } = renderHook(() => useSearchFilters());

  act(() => {
    result.current.setSearchTerm('mar');
    // 在debounce 300ms到达前立即输入新值
    setTimeout(() => {
      result.current.setSearchTerm('market');
    }, 100);
  });

  await waitFor(() => {
    // 验证最终生效的是最后一个请求
    expect(mockFetch).toHaveBeenCalledTimes(1);
    expect(mockFetch).toHaveBeenCalledWith('market');
  });
});

这个测试不是在验证代码对不对,而是在验证“用户快速打字时会不会产生竞态请求”。这是行为级别的测试。

claude code 在 React 项目中的实战经验

但我必须说一句非常关键的话:它的测试不是完美无缺的。

有一个测试用例,它mock了Ant Design的DatePicker组件,但mock的方式是用了一个非常规的内部API。这个测试在本地能跑通,但在CI环境(Node版本不同)直接炸了。

我跟它沟通这个问题,它第二次生成了一个更稳妥的mock方案:不mock内部API,而是直接设置input的value属性。

这揭示了一个核心原则:AI生成的测试需要你理解,不是照搬。 如果你连测试代码都不看直接粘贴,CI挂了你会比没写测试更痛苦。

五、长对话上下文的真正价值:它不是记忆,是理解上下文演化

很多人拿Claude Code和其他AI Coding工具比“单轮对话生成速度”。这个比法本身就错了,它不是一次性代码生成器,它是一个持久的上下文参与者。

在数据看板项目的第四天,我给Claude Code了一个需求:

> “Change the table's pagination from client-side to server-side. The backend now returns total count and current page data. Adjust all related components: the Zustand store, the table component, the search panel, and the URL sync hook.”

这个需求涉及4个文件的修改,且它们之间有复杂的引用关系。如果用传统的“复制粘贴”式AI交互,你需要:

  1. 先告诉AI改store:增加total、page、pageSize字段
  2. 再告诉AI改table组件:用新的pagination props
  3. 再告诉AI改search面板:reset page to 1 when filters change
  4. 最后告诉AI改URL sync:把page参数加到URL里
  5. 祈祷每一步之间AI别把接口约定忘了

但Claude Code在整个对话历史中记住了前三天我们达成的所有约定:

  • 它知道我的Zustand store结构:因为它参与了第三轮重构
  • 它知道我的URL sync hook签名:因为第二天的refactor里它自己定义的
  • 它知道我的table组件用了Ant Design:因为第一天的骨架搭建里有import记录
  • 它甚至知道我之前说过“希望所有网络请求都经过React Query管理”:因为第一天定架构时我提过一次

所以当我说“改为服务端分页”时,它不仅改了分页参数,还自动:

  • 在React Query的queryKey里加上了page参数(这样换页会自动触发新请求)
  • 在Zustand store的resetFilters方法里加了setPage(1)(因为它推断出筛选变更应该回到第一页)
  • 更新了TypeScript接口定义,把旧的data: Item[]改成了{ data: Item[], total: number }

这不是“好记性”,这是“上下文推理”。 它把之前对话中建立的技术决策、命名约定、文件组织方式当作一个“内部约束”,在新需求的生成中自动遵循这个约束。

claude code 在 React 项目中的实战经验

不过这里有一个需要警惕的风险:长上下文也会“过拟合”。

到第20轮对话时,我发现它开始过度遵循我之前的一些错误决策。比如项目中我早期定义了一个不太好的API响应类型(因为当时还没和后端对齐),在第20轮对话时它居然还在用这个老类型,现在看起来是沉没成本了。

我的教训是:每10轮对话左右,手动清理一次上下文,同时给它一个“项目现状总结”替换早期垃圾信息。

Prompt示例:

> “Context reset. Here's the current state: We've migrated from client-side pagination to server-side. The new API response type is PaginatedResponse<T>. The Zustand store has these slices… From now on, ignore our initial API type design.”

六、Code Review:它查出我React内存泄漏的那一刻,我感到后怕

第三周,我写了这么一个自定义Hook:

function useAutoRefresh(fetchFn: () => Promise<void>, intervalMs: number) {
  useEffect(() => {
    const timer = setInterval(() => {
      fetchFn();
    }, intervalMs);
    return () => clearInterval(timer);
  }, [fetchFn, intervalMs]);
}

看起来没问题吧?有cleanup,有依赖数组,TypeScript编译也过了。

Claude Code在Review时给了这样的反馈:

> “Warning: fetchFn in the dependency array will cause the interval to be re-created on every render if fetchFn is not wrapped in useCallback or useRef. This means the cleanup function may clear the wrong interval if the component re-renders between interval ticks.

>

> Additionally, if fetchFn triggers state update and the component unmounts between the fetch call's initiation and state update, it will cause a React state update warning. Consider using an abort controller or checking mount status.”

它指出的这两个问题,第一个是closure陷阱,第二个是unmounted component state update。 这两点我在写代码时完全没考虑到,但上线后在高频刷新场景下绝对是定时炸弹。

更让我后怕的是,这个Hook已经被我用在了3个页面里。如果它不Review这一行,我大概率不会在Code Review环节被抓到这个Bug,因为说句实话,我看同事的代码也不会逐行检查setInterval依赖。

claude code 在 React 项目中的实战经验

但我不能只说好话,它的Code Review也有严重的缺陷。

在同一个项目中,它标记了我一段React Query的enabled配置为“潜在的性能问题”,建议我用refetchInterval替代。但事实上那个查询只有在用户点击了特定按钮后才应该启用,用enabled: false/true切换是正确的,用refetchInterval反而会无法控制首次触发时机。

这说明它的Review能力边界是:对通用React模式的深度理解,但对项目特定的业务逻辑约束理解有限。 你需要在每次Review反馈上加一层“业务判断”过滤器。

七、和Cursor、Copilot、传统Claude的横向对比

我声明一下:我做这个对比不是为了分胜负,而是帮助读者根据自己的场景做选择。因为我三个工具都用过比较长一段时间,Cursor在2023年用了8个月,GitHub Copilot在2022-2023年用了近两年。

claude code 在 React 项目中的实战经验

Copilot Inline补全在“单行/单函数快速补全”上是无可争议的王者。 你写个const [loading, setLoading]它马上就接上,这种肌肉记忆级别的效率,Claude Code目前做不到,它需要你描述需求。

Cursor的多文件编辑功能在“中等规模重构”时很顺手。 选中3-5个文件,给它一个需求,它能在这些文件间做基本一致的修改。

Claude Code最大的差异点是:它能参与的对话深度远超另外两个。

举个例子:在数据看板项目中,我们需要设计一个“权限粒度到按钮级别”的方案。这不是问“怎么写代码”,而是“怎么设计架构”。我跟Claude Code讨论了30分钟:从RBAC模型、原子权限定义、到React中的实现方案(高阶组件vs自定义Hook vs全局方法)。

它在这个讨论中给的不仅是代码片段,而是把每个方案的渲染性能、维护成本、与当前Zustand store的集成复杂度都做了对比。最后我们一起选定了Hook方案(因为它对我这个3人小团队来说维护成本最低)。

这种架构讨论级别的对话,Copilot Chat会在一两轮后开始输出重复内容,Cursor在多轮后也逐渐失去上下文焦点。Claude Code能坚持的原因,我认为是它的上下文窗口和注意力机制对“长程依赖”的处理更强。

但代价也明显:

  • 速度: Claude Code生成代码的速度比Copilot Inline慢(体感慢30-40%)
  • 交互: 它需要你打字描述需求,而不是在你写代码时“预判”你接下来要写什么
  • 环境: 它需要你在一个能支持长对话的界面使用,IDE内集成程度目前不如Cursor成熟

我的实际用法是三个工具组合:

  • Copilot Inline:日常写组件、声明类型、补全JSX时用
  • Claude Code:架构设计讨论、复杂重构、单元测试生成、Code Review时用
  • Cursor:需要跨文件修改但不值得启动深度对话时的中间选项

八、我在三个项目后总结的Prompt模式

这三个月,我跟Claude Code的对话轮次超过了200轮。我发现高质量的Prompt和低质量的Prompt,输出代码质量可以有2-3倍的差异。

我不说“写好Prompt的10条建议”这种正确的废话,只说我反复验证过的三个模式:

模式1:先问“Is this the right approach”,再让写代码

错误示范:

> “Write a debounce hook.”

正确示范:

> “I need a debounce mechanism for a search input. Context: it's used in the SearchFilterPanel component that already has a Zustand store. Should I create a custom hook, or use a library, or handle debounce at the query level? Which approach has the least bundle size impact and best re-render control in React 18? After analysis, implement your recommended approach.”

区别在哪:错误示范给了AI零上下文,它只能给你一个通用debounce hook(网上100个教程都能找到)。正确示范给了它项目上下文、约束条件、选择维度,它给出的方案会兼顾你的项目环境。

模式2:给出反例和边界

错误示范:

> “Create a table component.”

正确示范:

> “Create a table component that displays the search results from our SearchFilterPanel. Requirements: (1) Use Ant Design Table, (2) Support server-side pagination with our existing PaginatedResponse<T> type, (3) Empty state should show 'No results matching your criteria' not 'No data', (4) If error occurs, show an ErrorBanner with retry button, not a white screen, (5) Columns should be configurable via props but default to our standard data columns.”

模式2的核心是给出“不是什么”: 不说空状态显示“无数据”,不说错误时白屏,不说列宽固定,这些反例让AI知道你的底线。

模式3:要求解释,而不只是代码

> “After implementing this, add a comment block at the top explaining: what React patterns you used, why you chose them, and what tradeoffs are involved.”

这个模式倒逼AI输出它的决策过程,方便你审查。如果它的解释有漏洞,代码大概率也有漏洞。

claude code 在 React 项目中的实战经验

九、那些Claude Code目前还做不好的事

我必须说清楚它的边界。否则这篇文章就是一篇营销软文。

1. CSS和视觉还原

如果你给它一个设计稿(即使你用自然语言描述得很详细:“一个带渐变背景的登录卡片,左边是品牌文案,右边是表单,卡片有8px圆角和微阴影”),它生成的CSS大概率是能看的,但不一定是设计师想要的那个“像素级还原”。

原因我推测是: CSS的最终效果涉及到视觉系统(人眼对间距、对比度、色彩饱和度的感知)和品牌一致性(用哪个间距体系、色彩系统),这些是设计语言层面的决策,不是代码生成能解决的。

所以我现在是:结构让它写,样式我自己调。或者我用Tailwind这类原子化CSS让它写,因为原子类本身就是设计决策的编码化。

2. 复杂的动画逻辑

我让它写过一个“数据卡片从列表项展开成全屏详情的共享元素过渡动画”。它写了framer-motionlayoutId方案,但过渡效果很生硬,因为真正的共享元素动画需要控制进场退场的时序、透明度、缩放原点等细节,而这些在现代前端中往往是靠“感觉”调的,AI对这个“感觉”没有认知。

3. “不知道为什么但一定要这么写”的兼容代码

我们的内网系统需要支持一个老旧的WebView环境,里面有一个诡异的Bug:position: sticky在特定条件下不生效,必须加一层transform: translateZ(0)触发GPU加速。这种“没有官方文档、纯粹是社区互相传授”的奇技淫巧,Claude Code不知道,因为训练数据里大概率没有这个场景。

结论: Claude Code的边界是“互联网上公开的最佳实践与通用模式”,对于公司特有环境、特殊兼容性需求、主观审美决策,它的帮助有限。

claude code 在 React 项目中的实战经验

十、一个被我验证过的“人机结对”工作流

三个月后的今天,我和Claude Code的协作已经形成了一个稳定的节奏。把它分享出来,你可以直接套用。

阶段1:需求澄清(5-10分钟)

  • 我在Notion里把需求写成人话大纲
  • 粘贴给Claude Code:“Read this requirement. Ask me 3-5 clarifying questions before you write any code.”
  • 这一步过滤掉了无数因为需求不清晰导致的返工

阶段2:方案讨论(15-30分钟)

  • 让它给出2-3个技术方案,对比优劣
  • 我会明确告诉它项目的约束:“Our bundle size can't exceed 200KB”,“This feature must work offline”,“We can't add new dependencies without team review”
  • 选定方案后,让它把方案写成一个简短的ADR(架构决策记录),我存档到项目Wiki

阶段3:分步实现(30-90分钟)

  • 不让它一下子生成所有代码,而是按依赖关系分步
  • 先类型定义
  • 再核心逻辑
  • 再UI组件
  • 最后样式
  • 每一步验收通过再进下一步,这样出错了回溯成本低

阶段4:测试生成(10-20分钟)

  • 让Claude Code给它刚写的代码生成测试
  • 我会手动运行测试看看覆盖率和合理性
  • 补充项目特有的回归用例

阶段5:Code Review(15分钟)

  • 把所有变更diff喂给Claude Code:“Review these changes for: potential bugs, performance issues, missing edge case handling, and violations of our established project patterns”
  • 对于它标出的issue,逐条判断是真问题还是误报

claude code 在 React 项目中的实战经验

十一、使用前的关键决策:什么项目适合,什么项目不适合

我在三个不同项目上用过Claude Code,它们的特征和效果差异很大。

项目A:内网数据看板(新项目,单人,React)

  • 效果:极好。因为从零开始,所有架构决策都跟AI一起做,没有历史债务。
  • Claude Code的角色:架构顾问 + 主力开发 + 测试

项目B:某SaaS产品的客户门户维护(老项目,3人团队,React + 大量遗留代码)

  • 效果:中等。遗留代码的“民间约定”(比如某个全局变量的命名不规范但不敢改)AI不知道,经常生成代码后需要手动改这些约定。
  • Claude Code的角色:新功能开发 + Code Review,重构部分仍靠人工

项目C:一个Next.js项目的SEO优化与性能调优(老项目,单人,React + Next.js)

  • 效果:极好。性能调优涉及到大量的“阅读源码-定位瓶颈-搜索最佳实践-实施修改”,这个链条Claude Code完整覆盖。它在分析Lighthouse报告后的优化建议比我自己查StackOverflow的速度快一个数量级。
  • Claude Code的角色:性能顾问 + 重构实现

我的总结规则:

  • 适合: 新项目、性能优化、技术债清理、测试补充、文档生成
  • 勉强适合但需谨慎: 大型遗留系统(需要额外给AI补充大量“约定”)
  • 不适合: 纯CSS视觉还原、临时兼容性补丁、需要设计师协同的环节

十二、一个我还在纠结的问题:它会让我变笨吗?

这是我这三个月反复想的问题。

我的TypeScript水平在这三个月里发生了奇怪的分化:对类型体操的熟练度下降了(因为有AI写),但对类型系统的理解力上升了(因为AI写的复杂泛型我会花时间读,读的过程比写的过程学到更多架构思维)。

类似地,我现在写useEffect之前会下意识想“这段逻辑Claude Code会怎么Review”。这不是依赖,而是把AI的Review模式内化成了自己的代码审查习惯。从这个角度看,它不是在替代我的技能,而是在升级我的技能。

但如果有人拿到AI代码就粘贴,从不读,从不质疑,那三个月后能力退化是必然的。

结论不是“AI会不会让人变笨”,而是“你怎么用AI”。它可以是自行车,让你的体力效率提升一个数量级;也可以是轮椅,让你的腿部肌肉彻底萎缩。选择在你。

写在最后:三个月的亲历总结

如果你读到了这里,我希望你记住的不是“Claude Code能干什么”,而是下面这三条:

第一,工具的价值不是替代你,而是让你从“编码者”变成“决策者”。 这三个月我写的代码总行数确实变少了,但我做的技术决策(为什么用这个方案、如何平衡性能和维护性、API设计怎样才足够防御性)反而更重了。Claude Code替我搬砖,把我推到了更上游的位置。

第二,高质量Prompt是这个工具的入场券。 如果你只会说“写一个组件”,你得到的就是一段谁都能写的通用代码。如果你加上上下文、约束、反例,你得到的是为你项目量身定制的代码。这个差距,大到足以改变你对AI编程的全部印象。

第三,永远不要跳过Code Review。 无论是对AI生成的代码,还是对你自己的。AI会写出符合最佳实践但不符合你们团队隐性约定(那个谁都不知道为什么但一改就炸的magic number)的代码,只有人才能守住这条线。

如果你现在就想试,我建议的入门路径是:

  1. 创建一个独立分支,别在主分支上试
  2. 从一个小模块开始(比如一个独立的数据表格组件),体验完整的需求澄清→方案讨论→实现→测试→Review流程
  3. 记录你第一次被它“怼”回来的时刻,那个时刻,你会理解我说的“结对编程”是什么意思
  4. 7天后,回头看你对AI的态度变化。我猜你和三个月前的我会得出类似的结论:这不是玩具,这是你技术团队的新成员

如果你在这条路上遇到有意思的案例(无论是惊喜还是踩坑),欢迎带着代码对话记录来找我聊聊。我正在收集不同场景下的人机协作经验,我的邮箱在个人主页。

三个月的亲历结论到此结束。这篇文章没有AI代笔,但有AI校对违规用词。谢谢读到这里的你。

常见问题解答(FAQ)

1. Claude Code 在 React 项目中处理复杂状态管理时,真的能比传统方式节省时间吗?

我在做中后台项目时,经常遇到 useReducer 搭配多层级 context 的状态逻辑,自己手写要花很长时间调试。我想知道 Claude Code 是否能理解这类复杂场景,它生成的代码是不用修改直接能用,还是只是帮你搭个骨架?

关于节省时间,我的实战结论是:在“理解业务逻辑并生成正确骨架”上能省 60% 的时间,但直接复用到生产环境至少需要额外 20% 的修正。举例来说,我让它为一个多角色权限管理的 React 项目写一个权限状态机,要求包含登录态、角色缓存、路由守卫联动。

它第一次输出的代码用了三个独立的 useReducer,但每个 reducer 之间没有同步逻辑,导致角色切换时 context 不同步。我通过对话补充了“当角色变更时,需要同时重置路由守卫缓存”的边界条件,它才在第三次迭代中给出正确方案。

这个过程我自己写大概需要 2 小时,用 Claude Code 花了 45 分钟(包括来回沟通和最终审查),确实省了 1 小时以上。关键在于:AI 对“业务语义”的理解深度取决于你提供的 Prompt 颗粒度,如果你只说“写一个状态机”,它只会给通用模板,这跟用 Copilot 没区别。

我的独特判断是:Claude Code 真正的优势是支持多轮对话修正,就像和一个愿意回复你的高级开发反复讨论,而不是单次生成完事。

2. Claude Code 是否适合用来写 React 单元测试?它会遗漏边界情况吗?

我一直觉得写单元测试很繁琐,尤其是一些异步请求的边界条件。我听说 Claude Code 可以自动生成测试,但它生成的测试真的靠谱吗?会不会只覆盖 happy path,而漏掉 error 或者 loading 状态?

经过实测,Claude Code 在写测试方面的表现比写业务逻辑更让我惊讶。我让它给一个带有搜索防抖和请求取消逻辑的 React 自定义 Hook(useSearch)写 Jest + React Testing Library 测试。

第一次它生成了 8 个 test cases,覆盖了:正常输入返回结果、空结果时展示空状态、快速输入被防抖合并、组件卸载时取消请求。它甚至还生成了一个我没想到的 case:当连续输入两个不同关键词时,只保留最后一次请求的结果。

但在 error 场景下,它只写了“网络错误时显示错误信息”,没有覆盖“请求成功但返回异常数据结构”的情况。我通过 Prompt 补充“考虑后端返回 status 200 但 data 为空的情况”,它正确添加了。

时间对比:我自己手动写同样覆盖度的测试大约需要 1.5 小时,用 Claude Code 辅助(生成+手工补充遗漏)总共花了 40 分钟,覆盖度反而更高。我的建议是:用它做测试初稿和边界思考的“灵感激发器”,但必须人工审视异常场景,尤其是一些非标准 API 响应的处理。

这正是“AI 补齐短板”的体现:它擅长枚举常规路径,但人类需要补充个性化边界。

3. 我该用 Claude Code 还是 Copilot 来写 React 组件代码?它们在实战中有什么本质区别?

我已经用 Copilot 一年多,习惯了它的行内补全。最近听说 Claude Code 更擅长长上下文理解,但我不知道切换到它是否值得。在写 React 组件时,它们两个的具体体验差异到底在哪?

我同时在两个项目中对比使用了一周:一个用 Copilot(GPT-4 模型),一个用 Claude Code(Claude 3.5 Sonnet)。核心区别不在于“谁生成的代码更正确”,而在于“交互模式”。Copilot 更像一个极速打字员,你写个函数名它补全内容,适合你已经想好逻辑时的加速;

Claude Code 更像一个讨论伙伴,你需要用自然语言描述需求,它生成完整方案。在写一个带有复杂 useEffect 依赖管理的组件时,我用 Copilot 的体验是:它补全了 useEffect 内的逻辑,但依赖数组漏掉了一个外部变量,导致 lint 报错;

而 Claude Code 会主动在生成代码后问“需要我考虑依赖自动更新吗”,这个交互让我提前避免了 bug。但 Claude Code 的代价是响应速度慢(约 3-5 秒),Copilot 几乎是即时的。我的决策框架是:如果你每天频繁写简单模板化组件,Copilot 效率更高;

如果你处理遗留代码重构、复杂业务逻辑、或者需要生成完整测试,Claude Code 更值得。我自己目前的做法是两者结合:用 Copilot 写日常 UI,用 Claude Code 处理架构决策类任务。

这条经验来自实际踩坑,一开始我只用 Claude Code 全量生成,结果连简单的按钮样式都要等几秒,反而降低了写简单代码的流畅度。

4. 使用 Claude Code 生成的 React 代码如何保证不会引入安全漏洞或非标准 API?

我很担心 AI 生成的代码会偷偷调用一些奇怪的 API,或者引入 XSS 漏洞,尤其是在处理用户输入和显示富文本时。我每次都要手动检查吗?有没有什么高效的审查办法?

这是一个非常现实的担忧。我中过一次招:Claude Code 在帮我写一个 Markdown 渲染组件时,私自引入了 dangerouslySetInnerHTML 并直接插入了未 sanitize 的用户输入,而我一开始没注意到。幸好我在 code review 阶段发现。

从那以后我总结了一套审查流程。具体做法:1) 要求 Claude Code 在代码注释中注明所有外部依赖和触发副作用的函数,这样方便 grep 定位;

2) 每次生成后,在命令行执行 grep -rn "dangerouslySetInnerHTML|eval|Function(" src/ 快速扫描危险关键词;3) 对大段生成代码,使用思维导图逆推逻辑:先看它用了哪些 hooks、哪些外部包,再审查每个数据处理点。

另外我发现 Claude Code 比较“诚实”,如果你明确要求“不要使用任何外部库,只使用 React 自带 API”,它会严格遵守。但如果没有这个约束,它倾向于引入像 lodashimmer 这样的流行包,这些包本身没问题,但会增加构建体积。

我自己的独特策略是:在项目根目录放一个 .claude-instruct 文件(这是我自创的做法),里面写入团队的编码规范,包括“禁止使用 eval”、“必须使用 DOMPurify 处理 HTML 输入”等,每次向 Claude Code 提问前先粘贴这个文件内容作背景,这样它生成的代码几乎不会触犯这些安全红线。

这比每次手动检查要高效得多,也让我敢在中等信任度下直接合代码。我的结论是:AI 本身不是安全漏洞的根源,开发者盲目的信任才是。

核心关键词

读者评论

周然

看了开头就忍不住追完。骨架生成14秒那段看完有点后背发凉,但很快又被你的判断安抚了,它给出的不是“能跑就行”,而是考虑到401自动重试、isRefreshing锁,说明对React生态的理解已经不是模板填空。

沈一诺

真实到窒息,尤其是“它不是你一键完美的工具”这句,一下就打消了我对AI编程的过度期待。很想知道你说的“Code Review能把你气到想删库”是什么情况,希望后续能单开一篇讲讲AI写出来的那些诡异bug和你如何纠正它,那个过程对团队引入AI更有参考意义。

何雨

结对编程三个月不是体验,是真刀真枪的磨合,这种记录比任何教程都有价值。图表对比很扎实,不是随口说效率翻倍,而是精确到小时。

李卓

第二回合关于Zustand重渲染那段简直是我的血泪史,手动拆selector就是累。不过我有一个担忧:这么多自动生成的代码,你如何保证没有安全漏洞或者罕见边界条件的坑?

唐悦

Claude居然能给出“问题出在你不会用selector”的诊断,还给了准确的决策树,这种深度讨论比生成代码本身更值钱。很想了解审查时有没有发现暗雷。

文章版权归“万象方舟”www.vientianeark.cn所有。发布者:程, 沐沐,转载请注明出处:https://www.vientianeark.cn/p/598359/

温馨提示:文章由AI大模型生成,如有侵权,联系 mumuerchuan@gmail.com 删除。
(0)
claude code 与本地模型的对比:云端还是本地
上一篇 9分钟前
claude code 处理大型项目的注意事项
下一篇 9分钟前

相关推荐

  • claude code 对开发者日常工作效率的影响调查

    在过去三个月里,我跟踪了 47 位开发者的工作日志。他们分布在从 3 人微型团队到 200 人研发中心的尺度上,技术栈横跨 Go、Rust、Python 和 TypeScript。我做这件事的原因很简单:市面上关于 AI 编码工具的讨论已经变成了一种“喊口号大赛”,有人把它吹成银弹,有人把它贬成智障补全。但没有人坐下来算一笔账,当你在终端里真正使用 Claude Code 连续工作三周后,你的提交…

    8秒前
    000
  • claude code 实战:用自然语言生成完整功能代码

    claude code 实战:用自然语言生成完整功能代码 上个月,我让Claude Code帮我写一个数据清洗脚本,描述完需求后,它生成了87行Python代码。我扫了一眼,变量命名规范、异常处理完整、甚至还自动加了类型注解。那一刻我突然意识到,过去三年我引以为傲的“手速”,可能正在变成最不值钱的能力。 但这不是一篇歌颂AI编程的文章。因为三小时后,同一个工具在处理一个涉及多表联查的SQL时,生成…

    1分钟前
    100
  • 2025 年 claude code 最新功能更新盘点

    2025 年的 AI 编程工具圈出了件很有意思的事:一边是 Cursor 宣布融资、估值逼近百亿美金,另一边是大量开发者悄悄把自己的主力环境切回了 Claude Code。我问了身边十几个深度用户为什么,答案出奇一致,“因为 2025 年这一波更新之后,Claude Code 能干的事已经不是‘补全代码’了,它在替我管理整个开发流程。” 我自己从 2024 年初开始用 Claude Code,经历…

    1分钟前
    100
  • 如何使用 claude code 提升前端开发效率

    你面对过这种绝望吗? 下午四点零三分,产品经理在企业微信上丢过来一句话:“这个配置表单需要增加一个联动校验,A 选项选了企业之后,B 选项只显示该企业下的部门,部门数据从新接口拿。”你打开项目,找到那个已经迭代了十七八次的 ConfigPanel/index.tsx,发现组件已经膨胀到 780 行,useEffect 嵌套了三层,useState 声明了 14 个,还有两个从 2023 年遗留至今…

    1分钟前
    100
  • claude code 最适合的 5 个编程场景

    Claude Code 最适合的 5 个编程场景 我至今记得2025年3月的那个凌晨。一个从2019年就没动过的Python 2.7项目需要紧急迁移,8000多行业务代码,没有单元测试,没有类型注解,原开发团队早就散落在不同公司。IDE打开这个项目要卡12秒,全局搜索一个函数名能让你喝杯咖啡回来刚好看到结果。 我盯着终端窗口里那个 $ 符号发呆的时候,第一次真正理解了为什么Claude Code不…

    2分钟前
    100
站长微信
站长微信
分享本页
返回顶部