聊天机器人之战

ChatGPT vs. Bard vs. Bing: 谁能通过React测试?

ChatGPT中文站

ChatGPT、Bard和Bing都是生成式人工智能聊天机器人,它们不仅能够像人类进行对话,还可以作为专家系统。ChatGPT使用了OpenAI的大型语言模型Generative Pretrained Transformers(GPT),而Bard则是基于Google的LaMDA和PaLM大型语言模型构建的。另一方面,Bing使用的是OpenAI的GPT-4。

我决定通过让这些聊天机器人解决一个简单但棘手的React问题来进行测试。这个简单但棘手的问题涉及使用函数组件创建一个React应用程序,以显示用户可以通过鼠标点击触发的计时器。如果你想知道如何自己解决这个问题,请查看本文章。

首先,我将在聊天机器人上使用以下提示:“使用功能组件创建一个React应用程序,该应用程序在鼠标单击时启动计时器”。然后,我将测试他们编写的代码,最后审查其代码,看看他们做对了哪些事情,哪些事情做错了。

ChatGPT

让我们从ChatGPT开始。这是ChatGPT想出来的代码:

现在让我们测试这段代码,看看它是否可以工作。

它运作了!

现在,让我们看看必应的表现如何。这是必应给我的代码:

这行得通吗?让我们检查一下。

ChatGPT中文站

毫不意外的是,运行在GPT-4之上的必应也能做到。

Bard (巴德)

现在让我们检查一下Bard是否也可以做对。这是Bard产生的代码:

很遗憾,这段代码包含一个错误。stopTimer函数中使用的interval变量实际上是在startTimer函数内部定义的局部变量。我们需要interval变量来清除计时器。因此,您可能认为将interval变量声明移动到startTimer函数之外可以修复这个错误。是的,这确实可以修复错误,但是您仍然无法停止计时器。这是因为React通过调用函数组件重新呈现。因此,在每次调用时,interval变量将被重新初始化。这意味着当我们调用stopTimer函数时,interval变量将没有引用到setInterval函数的输出。

那么,我们该怎么做呢?为了在重新渲染时保留数据,我们可以使用引用。因此,让我们使用引用重写代码。

现在让我们运行这段代码并检查它是否有效。

哎呀,它仍然无法正常工作,因为计时器拒绝移动超过1秒。那么,这里出了什么问题呢?答案在于我们在setInterval函数的回调函数中设置秒数状态的方式。

理解React中渲染的工作原理

在React中,状态就像其他普通变量一样,我们使用setState函数来更新其值。当我们调用该状态的setState函数时,React通过调用该函数重新渲染组件。当React调用此函数时,它将状态变量设置为其最新值。

所以,在这里,秒钟的初始值为0。当我们点击按钮调用startTimer函数时,该函数会调用setInterval函数。setInterval函数的回调函数将现有的秒钟值增加1。由于初始值为0,因此该值变为1。但是,由于在秒钟值为0时调用了startTimer,它无法看到对该值的最新修改。因此,即使setInterval函数第二次触发回调函数,它仍将从0到1递增。这意味着计时器不会超过1。

ChatGPT中文站

那么,我们该如何解决这个问题呢?很简单,我们只需要使用setState方法的功能更新器形式。这种形式接受回调函数而不是值。回调函数将最新的状态值作为参数接收。通过递增这个值,我们可以确保定时器正常工作。

ChatGPT中文站

那么,谁赢得了React之战?

巴德显然已经失去竞争力,因为我们甚至无法运行代码。ChatGPT和Bing都提供了可行的解决方案。从他们的代码中,我们可以看到他们都使用了useEffect钩子函数来设置和清除setInterval定时器。

ChatGPT的React代码中的缺陷

ChatGPT,在 isActive 和 seconds 状态改变时调用 useEffect 钩子的回调函数。这意味着该回调函数将随着每秒更新的秒数值而每秒调用一次。因此,每秒钟,间隔都将被清除,然后设置新的间隔。这是浪费的。那么,为什么我们要在秒数变化时触发回调函数呢?那是因为当 isActive 变为 false 时,我们检查秒数是否不等于 0 才清除间隔。这个检查有什么用处呢?

当我询问ChatGPT关于这个问题时,我收到了以下回复:

`useEffect` 钩子函数中 `seconds !== 0` 的目的是防止当计时器暂停时立即调用 `clearInterval` 函数。当计时器处于活动状态时,会设置 `setInterval` 函数以每秒钟增加 `seconds` 的状态值。

当定时器被暂停时(即`isActive`变为`false`),`clearInterval`功能被调用以停止间隔并防止进一步增加`seconds`状态。

然而,如果在计时器暂停后立即调用 `clearInterval` 函数,则 `seconds` 状态将被重置为0。为避免在暂停计时器时将秒数重置为0,我们添加条件 `seconds !== 0`。这可以确保仅当计时器已运行且 `seconds` 大于0 时才调用 `clearInterval` 函数。

总之,条件“秒数!== 0”确保只有在计时器运行而不是立即暂停之后才调用“clearInterval”函数。

这没有任何意义。清除间隔无法重置秒数值。而且,由于回调函数返回一个清除间隔的方法,当isActive状态改变时间隔将被清除。因此,我们可以删除这个多余的检查并从依赖中删除秒状态。这样我们就可以防止间隔被清除并每秒设置。

Bing的React代码中的缺陷。

另一方面,Bing 仅会在 timerOn 状态改变时清除间隔。但令人惊讶的是,在应用程序中,只有一次更新此状态,因为代码不允许我们在启动计时器后暂停它。不过,与 ChatGPT 的代码中可能对计时器精度产生很大影响的缺点相比,这只是一个小问题。

然而,ChatGPT和Bing都会在按钮状态改变时清除间隔。这是代码中的一个错误,因为当我们进入else块时,间隔变量将变为空,因为我们仅在if块内分配了一个setInterval函数的引用。因此,在ChatGPT的代码中,唯一允许计时器暂停的是useEffect回调返回的clearInterval函数调用。因此,我们可以将两个代码中的else块全部删除,应用程序仍将正常运行。

此外,在Bing的代码中,timerOn状态是完全冗余的,因为我们在任何地方都没有使用它。因此,我们可以摆脱它,在单击处理函数中调用setInterval函数。

这是更新后的必应代码:

以下是更新后的ChatGPT代码:

所以,必应和ChatGPT之间的战斗谁会获胜?尽管必应和ChatGPT都产生了功能代码,但它们的代码都不是最优的。但考虑到ChatGPT的错误对计时器准确性的影响很小,我会宣布必应为获胜者。然而,从这三个聊天机器人产生的代码中,我们可以安全地得出结论,它们都没有牢固掌握React。

2023-10-20 16:52:46 AI中文站翻译自原文