React 函数组件和类组件的区别,让 Codex 走 TaoToken 逐条对照

发布时间:2026/9/14 3:07:26
React 函数组件和类组件的区别,让 Codex 走 TaoToken 逐条对照 1. rfc 和 rcc 模板生成了Codex 可以帮你把差别讲透在 VSCode 里装好 ES7 React/Redux/React-Native snippets 之后rfc 和 rcc 确实能一键生成函数组件和类组件但模板生成不等于理解区别。真正卡住开发者的是 useState/useEffect 和 this.setState/componentDidMount 之间那层对应关系。我的习惯是让 Codex 走 TaoToken 逐条对照先打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 拿 Key再让 AI 把两段模板拆开讲。这样既能把 React 概念过一遍又能顺手验证 API 通道是否通。1.1 快捷指令真正生成了什么在编辑器里输入 rfc 回车会得到一段函数组件骨架import React from react export default function App() { return ( div /div ) }输入 rcc 回车得到的是一段类组件骨架import React, { Component } from react export default class App extends Component { render() { return ( div /div ) } }插件替你省掉了敲壳子的时间但有两件事它教不会。第一函数组件里没有 thisprops 是参数的解构类组件里所有数据访问都得绕一圈 this.props、this.state。第二类组件模板默认带 render 方法而函数组件的 return 就相当于 render 里的内容。很多人在模板里填业务时会把类组件的写法原样搬进函数组件然后对着报错标记发愣。与其反复翻文档不如把这两段模板交给 Codex让它逐行指给你看。你需要做的只是在 Codex 的配置里补一个 Base URL让请求从 TaoToken 走。整个准备过程用不了一分钟。1.2 在 ~/.codex/config.toml 里把 Codex 指向 TaoTokenCodex 的配置文件和 Claude Code 不一样它读的是 ~/.codex/config.toml。网上那些教你把 ANTHROPIC_BASE_URL 环境变量搬过来的方案对 Codex 无效Codex 认的是 model_provider 配置块。打开没有就新建这个文件追加下面这段# ~/.codex/config.toml model_provider taotoken model YOUR_MODEL_ID [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat其中 YOUR_MODEL_ID 要替换成 TaoToken 模型广场里真实存在的模型 ID不要照抄旧教程里带日期后缀的编号。然后把 API Key 放进环境变量export TAOTOKEN_API_KEYYOUR_API_KEYYOUR_API_KEY 是在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 注册后创建的不是猜出来的字符串。注意两个地址的分工注册、建 Key、看模型广场、看用量都在落地页 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end真正填进 Codex 配置的 Base URL 是 https://taotoken.net/api末尾不要加 /v1。2. 让 Codex 用同一段业务逻辑生成两个版本2.1 语法差异先看主语是谁函数组件是「一个函数接收 props返回 JSX」它不需要引入 Component也不需要 render 方法。类组件则是「一个 class 实例内部通过 this.props 读取数据、通过 this.render() 输出界面」。最简单的观察方式是让 Codex 用同一个「展示用户名和邮箱」的需求分别写两个版本。我建议的提示词长这样你面前有两段模板一段是 VSCode 里 rfc 生成的函数组件一段是 rcc 生成的类组件。 现在分别用它们实现同一个组件接收 props 里的 user 对象展示 name 和 email。 请输出两个版本并用注释标出“类组件里哪一行是因为 this 才存在的”。Codex 经过 TaoToken 返回后你会看到一份非常直观的对照。函数组件里function Profile({ user })直接把 props 解构了类组件里class Profile extends Component的 render 内部必须写const { user } this.props。两版业务代码完全一样但读取数据的路径不同。类组件的「复杂」并不在于多写了几行而是 this 把数据来源藏在了实例里读代码时要把上下文拼起来才能看懂。2.2 状态初始化与更新逻辑的写法对比把话题推进到状态。拿一个计数器为例函数组件用 useStateimport React, { useState } from react export default function Counter() { const [count, setCount] useState(0) return ( div p{count}/p button onClick{() setCount(count 1)}加一/button /div ) }类组件则是在 class 内部声明 state更新必须走 this.setStateimport React, { Component } from react export default class Counter extends Component { state { count: 0 } handleAdd () { this.setState((prev) ({ count: prev.count 1 })) } render() { const { count } this.state return ( div p{count}/p button onClick{this.handleAdd}加一/button /div ) } }这里隐藏着一个新手最容易踩的坑this.setState 是浅合并在 class 属性或事件里连续调用两次时React 会把同一轮里的更新批量合并而 useState 的 set 函数没有这个合并行为。如果代码里写setCount(count 1)连续两次结果不是加二因为两次拿到的 count 是同一个值。类组件用函数式this.setState((prev) ...)可以规避函数组件也要改成setCount((prev) prev 1)。这块别让 Codex 只口述直接要求它生成一个可以粘贴进本地项目的演示组件你本地跑起来多按几次按钮控制台打印出来的 count 看两遍就懂了。3. useState/useEffect 和生命周期方法的对应关系3.1 先记住这张迁移对照表如果你正在把一个类组件往函数组件迁移最该记住的是一张映射表类组件生命周期方法函数组件对应写法componentDidMountuseEffect(() { ... }, [])componentDidUpdateuseEffect(() { ... }, [依赖值])componentWillUnmountuseEffect(() { return () { ... } }, [])注意 componentDidMount 和 componentDidUpdate 在很多组件里会同时出现挂载时要拉数据某个 props 变化时也要重拉。类组件里要分开写两个方法函数组件里可以拆成两个独立的 useEffect每个 effect 只干一件事。让 Codex 对照翻译时要明确要求它「把请求逻辑放一个 effect把依赖项变化后的重算放另一个 effect」不然 AI 容易把所有状态更新揉进一个 effect 里。一个可以反复使用的提示词把下面这个类组件改写成函数组件要求 1. componentDidMount 中的请求逻辑放到 useEffect 中并在注释里说明依赖数组为什么是空的 2. componentWillUnmount 里的清理逻辑用 effect 的 cleanup 函数返回 3. 逐行解释 this.setState 那几行在函数组件里怎么写3.2 cleanup 是函数组件最容易漏的细节类组件在卸载时执行 componentWillUnmount函数组件里对应的不是 useEffect 本身而是 useEffect 返回的那个函数。刚转函数组件的人经常忘记在 effect 里 return结果定时器没清、事件没解绑、订阅一直挂着。举一个最常见的定时器场景。类组件写法是在 componentDidMount 里this.timer setInterval(...)在 componentWillUnmount 里clearInterval(this.timer)。函数组件要在一个 effect 里同时完成useEffect(() { const timer setInterval(() setNow(new Date()), 1000) return () clearInterval(timer) }, [])这里藏着一个比清定时器更深的点函数组件的 cleanup 不只在卸载时执行而是会在下一次 effect 运行前先执行上一轮的 cleanup。也就是说依赖数组从 [a] 变成 [b] 时先跑上一次清理再跑当前逻辑。这一点和 componentWillUnmount 有本质区别。如果你被这段绕晕就让 Codex 写一个带 console.log 的演示组件记录「effect 开始」「cleanup 执行」「卸载」三个日志然后你本地启动项目观察依赖变化时控制台的打印顺序。让 Codex 生成的组件在你本地跑再把输出贴回对话里问它为什么是这个顺序比死记概念管用。4. 优缺点不能背结论让 Codex 结合项目判断4.1 类组件留存的常见理由函数组件是当前推荐的写法这没错但「推荐」不等于「所有类组件都必须马上推翻」。类组件还有几个函数组件目前补不上或者补起来很别扭的场景第一Error Boundary。React 的错误边界组件至今仍推荐用类组件实现因为函数组件没有直接的 componentDidCatch 对应物。第二getSnapshotBeforeUpdate 这类生命周期需要同步读取 DOM 变化前后的快照函数组件没有一个完全等价的 Hook。第三老项目里已经积了大量类组件、HOC 和装饰器强行迁移的代价远大于收益。你可以把项目的目录结构喂给 Codex问它这样几个问题扫描 src/components 下目前的组件风格然后列出 1. 哪些组件是函数组件哪些是类组件 2. 类组件里哪些属于“纯展示 局部 state”可以低风险转成函数组件 3. 哪些因为 Error Boundary、refs、getSnapshotBeforeUpdate 等原因暂时不适合迁移注意Codex 只能基于你贴给它的代码做静态分析不能直接连上你的生产环境自动改代码。它给出的迁移清单要当成代码评审意见来读最终改动在编辑器里人工确认跑测试后再合入。4.2 函数组件的性能收益从哪里来函数组件的「轻量」不是指运行时一定比类组件快而是它的写法让 React 有更多优化空间。类组件里要减少子组件重渲染通常用 PureComponent 或者手写 shouldComponentUpdate函数组件则用 React.memo 包裹整个组件再配合 useMemo、useCallback 精确控制某个值或函数的引用。一个典型的性能优化写法const ListItem React.memo(function ListItem({ item, onSelect }) { return div onClick{() onSelect(item.id)}{item.title}/div })配合 useCallback 让父组件在每次渲染时保持 onSelect 引用稳定子组件就不会被无意义地重渲。类组件里同样的事情要做两遍先声明一个箭头函数属性保证 this 绑定正确再处理 PureComponent 的浅比较限制。函数组件在这类场景下代码结构确实更直接。关于「性能更好」这个结论不要直接背下来让 Codex 做一次对照实验。给它一个渲染一万行列表的描述让它分别用类组件加 PureComponent、函数组件加 React.memo 实现你本地跑起来在 React DevTools 里开 Highlight updates观察拖动滚动条时哪些组件高亮了。让 AI 生成实验代码让本地运行结果告诉你答案这比任何博客结论都可靠。5. 验证这次对照调用顺便排掉 /v1 和 401 的坑5.1 这次对话消耗了多少 token当 Codex 第一次通过 TaoToken 返回完整回答后说明整条通道已经通了。之后你再追问「为什么 useEffect 依赖数组不能省略」「class 属性为什么要用箭头函数」这类问题时就可以顺便打开落地页看用量了。回到 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 控制台能看到本次对照提问实际消耗的输入和输出 token 数。这个数字值得记下来因为你后面大概率会把整个项目里所有类组件都交给 Codex 做迁移预评估到时候每天要烧多少 token 就有依据了。确认请求正常返回、Token 正常计数之后再让 Codex 往深了走把你自己那份组件代码贴进去问它当前业务场景更适合函数组件还是类组件。这样每一次提问既在解决 React 问题又在为 API 通道做健康检查一举两得。5.2 最常见的三个配置错误排障优先级从高到低第一401 Unauthorized。绝大多数情况是环境变量里的 key 不是从 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 创建的或者复制时多带了一个空格、一个换行。检查一下echo $TAOTOKEN_API_KEY的值确认开头结尾没有多余字符。第二模型不存在。Codex 报 model not found说明 model 字段写了不存在的 ID。去 TaoToken 落地页的模型广场看当前可用的模型 ID用你实际看到的那串字符替换 YOUR_MODEL_ID不要沿用旧教程里的编号。第三Base URL 末尾加 /v1。Codex 的 wire_api 配置会自己负责路径拼接只需要填 https://taotoken.net/api。如果加了 /v1请求会打到不存在的路径上返回 404 或路由错误。改完配置后完全退出 Codex 再重新打开配置文件才会重新加载。如果你已经配好了现在就去 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 创建一个新的 Key把刚才那三个问题——模板差异、状态映射、生命周期映射——拆成三次小对话让 Codex 回答。等你能不看笔记回答出 useEffect 依赖数组三种写法各自的效果时你再回到 VSCode 里敲 rfc 或 rcc心里浮现的就再也不只是两段模板代码而是这两段模板背后各自的状态流、渲染时机和生命周期轨迹。