
chakra-ui-migrate
热门将 Chakra UI 项目从 v2 迁移到 v3,涵盖包更改、codemod、Provider 设置、颜色模式、属性重命名、复合组件、主题、recipes 和 Next.js 更新。每当用户升级 Chakra UI 版本、升级后遇到破坏性更改、转换旧的 v2 模式(ColorModeScript、useColorModeValue、styleConfig、extendTheme、isDisabled、colorScheme、@chakra-ui/icons、framer-motion 依赖)、修复复合组件模式,或询问 Chakra UI v2 和 v3 之间的差异时,使用此技能——即使他们没有明确说“迁移”或“升级”。
将 Chakra UI 项目从 v2 迁移到 v3,涵盖包更改、codemod、Provider 设置、颜色模式、属性重命名、复合组件、主题、recipes 和 Next.js 更新。每当用户升级 Chakra UI 版本、升级后遇到破坏性更改、转换旧的 v2 模式(ColorModeScript、useColorModeValue、styleConfig、extendTheme、isDisabled、colorScheme、@chakra-ui/icons、framer-motion 依赖)、修复复合组件模式,或询问 Chakra UI v2 和 v3 之间的差异时,使用此技能——即使他们没有明确说“迁移”或“升级”。
Chakra UI 迁移:v2 → v3
您正在指导开发人员将其项目从 Chakra UI v2 迁移到
v3。请按顺序完成以下步骤。首先检查项目——切勿
猜测包版本或框架。
Node 要求: Chakra UI v3 需要 Node >= 20.x。如果环境不确定,请先确认。
步骤 1 — 检查项目
阅读这些文件以了解当前状态:
package.json
查找:
- 当前的
@chakra-ui/react版本(v2.x 与 v3.x) - 相关包:
@chakra-ui/icons、@chakra-ui/hooks、
@chakra-ui/next-js、@emotion/styled、framer-motion - 框架:Next.js(App Router 或 Pages Router)、Vite、纯 React
- 包管理器(根据锁文件:
pnpm-lock.yaml、yarn.lock、bun.lock、
package-lock.json)
在有用时抽查关键文件:
- Provider / 主题设置(
_app.tsx、layout.tsx、theme.ts) - 颜色模式使用(
ColorModeScript、useColorMode、useColorModeValue) - 任何显示大量 v2 模式的组件文件
步骤 2 — 更新包
移除仅 v2 的依赖
# npm
npm uninstall @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
# pnpm
pnpm remove @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
# yarn
yarn remove @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
@emotion/styled 和 framer-motion 在 v3 中不再需要。
安装 v3 核心包
# npm
npm install @chakra-ui/react @emotion/react
# pnpm
pnpm add @chakra-ui/react @emotion/react
# yarn
yarn add @chakra-ui/react @emotion/react
已移除包的替代品
| 已移除 | 替代品 |
|---|---|
@chakra-ui/icons |
lucide-react 或 react-icons |
@chakra-ui/hooks |
react-use 或 usehooks-ts |
@chakra-ui/next-js |
asChild 属性模式(参见 Next.js 部分) |
步骤 3 — 运行 codemod
官方 codemod 处理大多数机械更改:组件重命名、属性
更新、导入重写和复合组件重构。它不能替代手动审查——计划审查输出。
先进行试运行(不更改文件):
npx @chakra-ui/codemod upgrade --dry
审查其建议。满意后:
npx @chakra-ui/codemod upgrade
在 codemod 之后,先提交更改,然后再进行手动编辑,以便有干净的差异。
步骤 4 — 更新 Provider
旧的 v2 模式
// v2
import { ChakraProvider } from "@chakra-ui/react"
import theme from "./theme"
;<ChakraProvider theme={theme}>{children}</ChakraProvider>
新的 v3 模式(使用 Chakra CLI 片段)
生成 Provider 和组件片段:
npx @chakra-ui/cli snippet add
这将创建 components/ui/provider.tsx(以及 toaster 和 tooltip
片段),并自动安装所需的 npm 依赖——包括
next-themes。导入并使用它:
// v3 — app/layout.tsx(Next.js App Router)
import { Provider } from "@/components/ui/provider"
;<html lang="zh" suppressHydrationWarning>
<body>
<Provider>{children}</Provider>
</body>
</html>
Provider 文件包含 "use client"——不要将其添加到 layout.tsx。有关 Pages Router 的放置位置,请参阅 Next.js 部分。
v3 中的自定义主题
用 createSystem 替换 extendTheme:
// v2
import { extendTheme } from "@chakra-ui/react"
// v3
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
export const theme = extendTheme({ colors: { brand: { 500: "#2196f3" } } })
const config = defineConfig({
theme: { tokens: { colors: { brand: { 500: { value: "#2196f3" } } } } },
})
export const system = createSystem(defaultConfig, config)
通过 value={system} 将 system 传递给 ChakraProvider。
步骤 5 — 颜色模式迁移
移除所有 v2 颜色模式模式
// 移除这些 v2 导入和使用:
import { ColorModeScript } from "@chakra-ui/react"
// ❌
import { useColorMode } from "@chakra-ui/react"
// ❌(使用 next-themes)
import { useColorModeValue } from "@chakra-ui/react"
// ❌(使用 CSS 令牌)
import { DarkMode, LightMode } from "@chakra-ui/react"
// ❌
// 同时从 _document.tsx 中移除:
;<ColorModeScript initialColorMode={theme.config.initialColorMode} /> // ❌
v3 颜色模式方法
颜色模式由 next-themes 通过生成的 Provider 处理。使用
自动响应活动颜色模式的语义令牌:
// 使用 Chakra 语义令牌——它们在暗色模式下自动切换
<Box color="fg.default" bg="bg.subtle">
...
</Box>
对于颜色模式切换,使用生成的 components/ui/color-mode.tsx
片段或直接使用 next-themes 中的 useColorMode。
步骤 6 — 属性重命名
这些布尔和样式属性在 v3 中已重命名,以与 HTML 和
现代 React 约定保持一致。codemod 会捕获大多数这些更改,但之后请手动验证。
布尔属性
| v2 | v3 |
|---|---|
isOpen |
open |
defaultIsOpen |
defaultOpen |
isDisabled |
disabled |
isInvalid |
invalid |
isRequired |
required |
isReadOnly |
readOnly |
isChecked |
checked |
isLoaded |
loaded |
isIndeterminate |
indeterminate |
样式和布局属性
| v2 | v3 |
|---|---|
colorScheme |
colorPalette |
noOfLines |
lineClamp |
truncated |
truncate |
spacing(Stack) |
gap |
apply |
textStyle 或 layerStyle |
嵌套样式属性
// v2 — 带有嵌套伪选择器的 sx
<Box sx={{ "&:hover": { color: "blue.500" } }} />
// v3 — 带有 "&" 选择器的 css 属性
<Box css={{ "&:hover": { color: "blue.500" } }} />
步骤 7 — 组件迁移
重命名的组件
| v2 | v3 |
|---|---|
Modal |
Dialog |
FormControl |
Field |
Select |
NativeSelect |
AlertDialog |
AlertDialog(复合,见下文) |
Modal 是最常见的重命名——每个 <Modal>、<ModalOverlay>、
<ModalContent>、<ModalHeader>、<ModalBody>、<ModalFooter> 和
<ModalCloseButton> 都变成 Dialog.* 复合部分:
// v2
<Modal isOpen={open} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>标题</ModalHeader>
<ModalBody>正文</ModalBody>
<ModalFooter><Button onClick={onClose}>关闭</Button></ModalFooter>
</ModalContent>
</Modal>
// v3
<Dialog.Root open={open} onOpenChange={({ open }) => setOpen(open)}>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Header><Dialog.Title>标题</Dialog.Title></Dialog.Header>
<Dialog.Body>正文</Dialog.Body>
<Dialog.Footer><Button onClick={() => setOpen(false)}>关闭</Button></Dialog.Footer>
<Dialog.CloseTrigger />
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>
复合组件重写
v3 采用一致的复合组件 API。codemod 处理许多
这些,但复杂的自定义用法需要手动审查。
复选框
// v2
<Checkbox isChecked={val} onChange={fn}>标签</Checkbox>
// v3
<Checkbox.Root checked={val} onCheckedChange={fn}>
<Checkbox.Control><Checkbox.Indicator /></Checkbox.Control>
<Checkbox.Label>标签</Checkbox.Label>
</Checkbox.Root>
进度条
// v2
<Progress value={60} colorScheme="blue" />
// v3
<Progress.Root value={60} colorPalette="blue">
<Progress.Track><Progress.Range /></Progress.Track>
</Progress.Root>
手风琴
// v2
<Accordion><AccordionItem><AccordionButton /><AccordionPanel /></AccordionItem></Accordion>
// v3
<Accordion.Root>
<Accordion.Item value="item-1">
<Accordion.ItemTrigger />
<Accordion.ItemContent />
</Accordion.Item>
</Accordion.Root>
FormControl → Field
// v2
<FormControl isInvalid={!!error} isRequired>
<FormLabel>邮箱</FormLabel>
<Input type="email" />
<FormErrorMessage>{error}</FormErrorMessage>
<FormHelperText>我们绝不会分享您的邮箱。</FormHelperText>
</FormControl>
// v3
<Field.Root invalid={!!error} required>
<Field.Label>邮箱</Field.Label>
<Input type="email" />
<Field.ErrorText>{error}</Field.ErrorText>
<Field.HelpText>我们绝不会分享您的邮箱。</Field.HelpText>
</Field.Root>
所有 FormControl 子部分映射到 Field.*:
FormLabel→Field.LabelFormErrorMessage→Field.ErrorTextFormHelperText→Field.HelpTextFormControl属性isInvalid、isRequired、isDisabled→invalid、
required、disabled
Dialog / Drawer / Menu / Tabs 遵循相同的复合模式:使用
ComponentName.Root、.Trigger、.Content、.Item 等。查看 Chakra UI
v3 文档以了解每个组件的具体复合 API。
Next.js Image 和 Link(替换 @chakra-ui/next-js)
// v2 — @chakra-ui/next-js
import { LinkOverlay } from "@chakra-ui/next-js"
// v3 — asChild 模式
import NextLink from "next/link"
<ChakraLink asChild><NextLink href="/about">关于</NextLink></ChakraLink>
import NextImage from "next/image"
<ChakraImage asChild><NextImage src="..." alt="..." /></ChakraImage>
步骤 8 — 主题迁移
styleConfig 和 multiStyleConfig → recipes
// v3 — 单个组件(recipe)
import { defineRecipe } from "@chakra-ui/react"
// v2
const buttonStyle = {
baseStyle: { fontWeight: "bold" },
variants: { solid: { bg: "blue.500" } },
defaultProps: { variant: "solid" },
}
const buttonRecipe = defineRecipe({
base: { fontWeight: "bold" },
variants: { variant: { solid: { bg: "blue.500" } } },
defaultVariants: { variant: "solid" },
})
// v3 — 插槽 recipe
import { defineSlotRecipe } from "@chakra-ui/react"
// v2 — multiStyleConfig(多部分组件)
const cardStyle = multiStyleConfig({
parts: ["root", "header"],
baseStyle: { root: { bg: "white" }, header: { fontWeight: "bold" } },
})
const cardSlotRecipe = defineSlotRecipe({
slots: ["root", "header"],
base: { root: { bg: "white" }, header: { fontWeight: "bold" } },
})
自定义令牌的类型生成
添加自定义令牌、语义令牌、recipes 或插槽 recipes 后,运行
typegen 以保持 TypeScript 类型同步:
npx @chakra-ui/cli typegen ./theme.ts
复杂主题迁移 — 如果您正在迁移包含许多自定义令牌、语义令牌或多部分组件样式的大型 v2 主题,请使用
chakra-ui-theming技能。它深入涵盖了完整的令牌/recipe/插槽-recipe API,并且比本节更适合作为指南。
步骤 9 — Next.js 特定事项
App Router
- 将
<Provider>放在app/layout.tsx中(服务器组件——无"use client") - 生成的
components/ui/provider.tsx已包含"use client" - 在
<html>上添加suppressHydrationWarning以防止颜色模式闪烁 - 不要将整个应用或布局包装在
"use client"中
Pages Router
// pages/_app.js
import { Provider } from "@/components/ui/provider"
export default function App({ Component, pageProps }) {
return (
<Provider>
<Component {...pageProps} />
</Provider>
)
}
从 pages/_document.tsx 中移除任何 ColorModeScript——v3 中不使用它。
步骤 10 — 验证清单
迁移完成后,请完成以下检查:
- [ ] 重新安装依赖:
npm install/pnpm install - [ ] TypeScript:
npx tsc --noEmit— 解决所有类型错误 - [ ] Lint:
npm run lint - [ ] 构建:
npm run build - [ ] 目视验证颜色模式切换(浅色 ↔ 深色)
- [ ] 测试交互组件:Dialog、Drawer、Menu、Tabs、Accordion
- [ ] 测试表单组件:Checkbox、Select/NativeSelect、Input、Radio
- [ ] 检查关键页面是否有视觉回归
- [ ] 搜索代码库中残留的 v2 导入:
grep -r "ColorModeScript\|useColorModeValue\|extendTheme\|styleConfig\|@chakra-ui/icons\|@chakra-ui/next-js" src/
澄清问题(当上下文不明确时)
如果用户的版本、框架或范围不明确,请询问:
- "您当前使用的
@chakra-ui/react版本是什么?" - "您使用的是 Next.js App Router、Pages Router、Vite 还是纯 React?"
- "您是在迁移整个代码库还是仅迁移特定组件?"
如果您在未询问的情况下继续,请明确说明假设。





