现在很多前端开发遇到 Bug,第一反应已经不是先去 Stack Overflow,也不是翻半天官方文档,而是直接把代码丢给 AI。

但问题也随之出现了:

明明都是 AI,为什么有时候一个模型能直接指出问题,另一个模型却会给你改一大堆代码,最后 Bug 还在?

这次就拿一个 React 开发里非常常见、而且特别容易被 AI “带跑偏”的问题,做一次同题模拟对比。

为了避免把不同版本、不同时间的模型表现写死,下面主要比较 DeepSeek、豆包和 GPT 在这类问题中的典型分析路径和解决思路,不把它当成绝对排名。


一、先看这个 React Bug

假设页面里有这样一段代码:

import React, { useEffect, useState } from "react";

export default function UserList() {
  const [users, setUsers] = useState([]);
  const [keyword, setKeyword] = useState("");

  const params = {
    keyword,
    page: 1
  };

  useEffect(() => {
    fetch("/api/users?" + new URLSearchParams(params))
      .then(res => res.json())
      .then(data => {
        setUsers(data.list);
      });
  }, [params]);

  return (
    <div>
      <input
        value={keyword}
        onChange={e => setKeyword(e.target.value)}
        placeholder="搜索用户"
      />

      {users.map(user => (
        <div key={user.id}>{user.name}</div>
      ))}
    </div>
  );
}

乍一看,好像没什么问题。

逻辑也非常简单:

用户输入关键词 → keyword 改变 → 请求接口 → 更新列表。

但实际运行以后,你可能会发现一个很离谱的现象:

接口一直请求。

哪怕用户什么都没操作,Network 里也可能连续出现请求。

如果接口响应比较快,甚至有机会直接把后端接口刷爆。


二、问题到底出在哪?

真正的问题其实就在这里:

const params = {
  keyword,
  page: 1
};

以及:

useEffect(() => {
  // ...
}, [params]);

很多刚开始写 React 的开发者第一眼并不会意识到问题。

因为从人的角度看:

{
  keyword: "",
  page: 1
}

和下一次渲染得到的:

{
  keyword: "",
  page: 1
}

内容明明完全一样。

但 React 在判断依赖是否变化的时候,并不会帮你做对象内容的深度比较。

每次组件重新渲染时:

const params = {
  keyword,
  page: 1
};

都会创建一个新的对象引用

也就是说:

{} !== {}

所以 React 会认为:

params 又变了。

于是整个过程变成:

组件渲染
↓
创建新的 params
↓
useEffect 发现 params 变化
↓
请求接口
↓
setUsers
↓
组件重新渲染
↓
又创建新的 params
↓
useEffect 再执行
↓
继续请求

这才是真正的根因。


三、把这个问题交给不同 AI,会发生什么?

这里才是我觉得比较有意思的地方。

因为这种 Bug 本身并不难。

真正能拉开体验差距的,往往不是:

AI 知不知道 useEffect。

而是:

AI 能不能迅速判断“哪一行代码才是真正的根因”。


四、DeepSeek:答案通常比较直接

如果把整段代码和“为什么接口一直请求”这个问题交给 DeepSeek,比较容易得到类似这样的分析:

params 是一个对象,每次组件重新渲染都会创建新的引用,而 useEffect 依赖了 params,因此 React 会认为依赖发生变化,导致 Effect 重复执行。

然后一般会给出几个解决方案。

例如直接修改依赖:

useEffect(() => {
  const params = {
    keyword,
    page: 1
  };

  fetch("/api/users?" + new URLSearchParams(params))
    .then(res => res.json())
    .then(data => {
      setUsers(data.list);
    });
}, [keyword]);

这个答案其实已经能解决问题了。

对于这种单文件、问题明确、上下文比较少的 Bug,DeepSeek 的表现通常已经完全够用。

而且它的优势很明显:

中文解释比较自然。

对于国内开发者来说,直接把报错、代码和需求一起扔进去,使用门槛很低。


五、豆包:解释会更偏“教学型”

豆包面对这种问题时,一个比较明显的特点是:

它往往会把问题拆得更细。

比如不仅告诉你:

params 每次渲染都会重新创建。

还可能顺便解释:

  • 什么叫引用类型
  • useEffect 怎么比较依赖
  • 为什么数组和对象容易触发类似问题
  • useMemo 是干什么的
  • 为什么不能随便把对象放进依赖数组

例如可能给出这样的改法:

const params = useMemo(() => {
  return {
    keyword,
    page: 1
  };
}, [keyword]);

然后:

useEffect(() => {
  fetch("/api/users?" + new URLSearchParams(params))
    .then(res => res.json())
    .then(data => setUsers(data.list));
}, [params]);

这同样是正确方案。

对于刚接触 React 的开发者来说,这种回答其实挺舒服。

因为它不是只告诉你:

“改这里。”

而是会解释:

“为什么要改这里。”


六、GPT 的区别,往往不是“知道答案”

再看 GPT。

如果只是问:

为什么这个 useEffect 会无限请求?

其实三个模型都有很大概率答出来。

所以真正值得看的,并不是这一道题谁会做。

而是继续往下追问:

这个项目实际开发中应该怎么改?

这时候答案开始出现差异。

比较成熟的分析通常不会急着告诉你:

useMemo

而是先判断:

这个 params 有必要存在吗?

因为从当前代码看:

const params = {
  keyword,
  page: 1
};

只是为了发请求。

那最简单的方案其实不是增加一个 useMemo

而是直接把真正影响请求的状态作为依赖:

useEffect(() => {
  const searchParams = new URLSearchParams({
    keyword,
    page: "1"
  });

  fetch(`/api/users?${searchParams}`)
    .then(res => res.json())
    .then(data => {
      setUsers(data.list);
    });
}, [keyword]);

反而更简单。

这也是我觉得 AI 编程里一个很容易被忽略的问题:

能修好 Bug,不等于修改方案就是最合理的。


七、为什么“疯狂 useMemo”不一定是好答案?

看到对象引用变化以后,很多人会下意识写:

const params = useMemo(() => ({
  keyword,
  page: 1
}), [keyword]);

技术上当然没问题。

但如果整个项目里一碰到对象就 useMemo,代码很快就会变成:

const params = useMemo(...)

const options = useMemo(...)

const config = useMemo(...)

const filter = useMemo(...)

最后组件里到处都是缓存。

这其实属于:

为了 Hooks 而 Hooks。

真正应该考虑的是:

这个对象是不是一定需要成为组件渲染阶段的变量?

如果只是某一个 Effect 内部使用,很多时候直接放进 Effect 里反而更加清晰。

这类“代码能不能继续简化”的判断,才是我认为现在不同 AI 编程体验真正容易拉开差距的地方。


八、再继续追问一步:其实还有隐藏问题

如果这是一段真实业务代码,我还会继续问 AI:

用户快速输入关键词怎么办?

比如用户连续输入:

a
ab
abc
abcd

那就可能瞬间发送四次请求。

甚至还可能出现:

abcd 的请求先回来

abc 的请求后回来

结果旧数据把新数据覆盖了。

这时候问题已经不再是一个简单的:

useEffect 无限循环。

而变成:

  • 是否需要防抖
  • 是否需要取消旧请求
  • 如何避免竞态
  • loading 状态怎么处理
  • 请求失败怎么处理
  • 组件卸载以后是否还需要更新状态

真正用于生产环境的代码,可能会继续演进成:

useEffect(() => {
  const controller = new AbortController();

  const timer = setTimeout(async () => {
    try {
      const searchParams = new URLSearchParams({
        keyword,
        page: "1"
      });

      const response = await fetch(
        `/api/users?${searchParams}`,
        {
          signal: controller.signal
        }
      );

      const data = await response.json();

      setUsers(data.list);
    } catch (error) {
      if (error.name !== "AbortError") {
        console.error(error);
      }
    }
  }, 300);

  return () => {
    clearTimeout(timer);
    controller.abort();
  };
}, [keyword]);

你会发现:

最开始明明只是一个:

“为什么接口一直请求?”

最后其实可以延伸出完整的前端请求设计问题。


九、这才是我现在判断 AI 编程能力的方法

以前大家喜欢问:

哪个 AI 写代码最强?

但我现在越来越觉得,这个问题本身就太宽泛了。

因为如果只是:

写一个冒泡排序

或者:

写一个 React TodoList

现在很多模型都能完成。

真正应该测试的是:

第一,能不能找到根因

不是看到报错就开始改代码。

第二,能不能减少无意义修改

一个 Bug 最怕 AI 一次改十几个文件。

最后:

原来的问题没解决,又创造三个新问题。

第三,能不能理解真实项目环境

Demo 和真实业务完全是两回事。

真实项目还有:

  • 状态管理
  • 权限
  • 接口封装
  • TypeScript
  • ESLint
  • 路由
  • 请求缓存
  • 历史代码
  • 团队规范

第四,能不能继续往下发现问题

优秀的 AI 不应该只回答:

“这一行错了。”

而应该能进一步提醒你:

即使修改这一行,当前请求逻辑还有竞态风险。

这种能力在真正开发项目时,价值要高很多。


十、DeepSeek、豆包和 GPT,到底怎么选?

如果只是这一个 React Bug,我觉得完全没必要神化任何模型。

DeepSeek 能解决。

豆包也能解决。

GPT 同样能解决。

真正的区别,往往会随着任务复杂度增加才逐渐出现。

如果你的使用场景只是:

  • 看报错
  • 写 SQL
  • 查 API
  • 写一个函数
  • 解释代码

国内 AI 对很多开发者来说已经非常够用了。

但如果开始进入:

  • 大段代码分析
  • 连续 Debug
  • 多轮修改
  • 复杂业务逻辑
  • 项目级重构
  • 多文件上下文
  • 长时间协作开发

这时候才更值得认真比较不同模型。

我自己比较建议的是:不要一上来就纠结“谁最强”,而是把自己平时最真实的代码丢进去跑几天。

尤其是一直在用 DeepSeek、豆包,但还没有认真体验过 GPT 的开发者,实际拿同一个项目对比一次,感受会比看各种模型跑分直观得多。

如果后面确实发现 GPT 更适合自己的工作流,再考虑是否需要开通 Plus。国内支付不方便的,也可以自行了解一下 gpt211·com 这类 AI 订阅服务平台,不过第三方渠道还是建议先看清楚开通方式、售后规则以及是否需要提供账号密码,再决定是否使用。

这类东西没必要跟风。

能不能真正提高自己的开发效率,才是最重要的。


最后

这次这个 React Bug 本身其实很简单。

真正让我觉得有意思的,反而是一个变化:

以前程序员遇到 Bug,会搜索“这个问题怎么解决”;现在越来越多的人开始思考“这个问题应该交给哪个 AI 解决”。

而下一阶段,真正拉开效率差距的可能也不是:

你有没有使用 AI。

而是:

你能不能让 AI 真正理解你的项目,而不是只会让它生成几段看起来能运行的代码。

下一篇我准备继续拿一个更接近真实项目的问题测试:

“同一个 Spring Boot 接口响应变慢的问题,DeepSeek、豆包和 GPT 谁能真正定位到原因?”

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐