Chakra UI v3+Vite+React主题与按钮样式异常求助
问题:Instagram克隆项目样式异常,需调整为深色背景+黑色按钮白字
我正在跟随教程开发Instagram克隆,但当前页面显示白色背景、灰色按钮白字,想要实现深色背景+黑色按钮白字效果,已困扰多周,相关代码如下:
package.json
{ "name": "insta-clone", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vite build", "lint": "eslint .", "preview": "vite preview" }, "dependencies": { "@chakra-ui/react": "^3.0.0", "@emotion/is-prop-valid": "^1.3.1", "@emotion/react": "^11.1.0", "@emotion/styled": "^11.1.0", "framer-motion": "^12.9.1", "next-themes": "^0.4.6", "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^5.5.0" }, "devDependencies": { "@eslint/js": "^9.22.0", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", "@vitejs/plugin-react": "^4.3.4", "eslint": "^9.22.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.19", "globals": "^16.0.0", "vite": "^6.3.3", "vite-tsconfig-paths": "^5.1.4" } }
main.jsx
import React from 'react'; import ReactDOM from 'react-dom/client'; import { ChakraProvider } from '@chakra-ui/react'; import App from './App'; import theme from './themes/index'; ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <ChakraProvider value={theme}> <App /> </ChakraProvider> </React.StrictMode> );
App.jsx
import React from 'react'; import CustomButton from './themes/components/CustomButton' function App() { return ( <div> <CustomButton variant="primary" onClick={() => console.log('clicked')}>Click Me</CustomButton> </div> ); } export default App;
主题文件 themes/index.ts
import { createSystem, defineConfig, defaultConfig } from '@chakra-ui/react' import buttonRecipe from './foundation/recipes/button' const tokens = { colors: { bg: { default: '#121212', }, text: { default: '#ffffff', }, teal: { 400: '#38b2ac', }, }, radii: { md: '0.375rem', }, fontWeights: { semibold: 600, }, space: { 4: '1rem', }, } const theme = createSystem({ config: defineConfig({ initialColorMode: 'dark', useSystemColorMode: false, }), tokens, recipes: { button: buttonRecipe, }, }) export default theme;
themes/foundation/recipes/button.ts
import { defineRecipe } from '@chakra-ui/react' const buttonRecipe = defineRecipe({ base: { fontWeight: 'semibold', borderRadius: 'md', px: '4', py: '2', _hover: { opacity: 0.9, }, }, variants: { variant: { primary: { bg: 'teal.400', color: 'white', }, defaultVariants: { variant: 'primary', }, }, }, }) export default buttonRecipe;
themes/components/CustomButton.tsx
import React from 'react' import { Button } from '@chakra-ui/react' import { css } from '@emotion/react' interface CustomButtonProps { children: React.ReactNode variant?: 'primary' | 'secondary' [key: string]: any } const CustomButton = ({ children, variant = 'primary', ...props }: CustomButtonProps) => { console.log('Props:', props) const buttonStyles = { base: { fontWeight: 'semibold', borderRadius: 'md', px: '4', py: '2', _hover: { opacity: 0.9, }, }, primary: { bg: 'teal.400', color: 'white', }, secondary: { bg: 'gray.400', color: 'black', }, } console.log('Variant:', variant) console.log('Props:', props) const mergedStyles = { ...buttonStyles.base, ...(variant ? buttonStyles[variant] : {}), } return ( <Button {...props} style={{ fontWeight: 'semibold', borderRadius: 'md', paddingLeft: '1rem', paddingRight: '1rem', paddingTop: '0.5rem', paddingBottom: '0.5rem', backgroundColor: 'teal.400', color: 'white', }} > {children} </Button> ) } export default CustomButton
jsconfig.json
{ "compilerOptions": { "module": "ESNext", "moduleResolution": "node", "target": "ESNext", "jsx": "react-jsx", "baseUrl": "./", "paths": { "@ui/*": ["src/components/ui/*"], "@/*": ["src/*"] } }, "include": ["src/**/*"] }
解决方案
1. 修复ChakraProvider主题传递方式
Chakra UI v3中,ChakraProvider接收主题的属性是theme而非value,修改main.jsx:
<ChakraProvider theme={theme}> <App /> </ChakraProvider>
2. 设置全局深色背景
改用Chakra的Box组件作为根容器,继承主题中的深色背景:
修改App.jsx:
import React from 'react'; import { Box } from '@chakra-ui/react'; import CustomButton from './themes/components/CustomButton' function App() { return ( <Box minH="100vh" bg="bg.default" color="text.default"> <CustomButton variant="primary" onClick={() => console.log('clicked')}>Click Me</CustomButton> </Box> ); } export default App;
3. 调整按钮为黑色背景
修改按钮recipe的primary变体背景色为黑色:
修改themes/foundation/recipes/button.ts:
const buttonRecipe = defineRecipe({ base: { fontWeight: 'semibold', borderRadius: 'md', px: '4', py: '2', _hover: { opacity: 0.9, }, }, variants: { variant: { primary: { bg: 'black', color: 'white', }, defaultVariants: { variant: 'primary', }, }, }, })
4. 简化CustomButton组件
去掉硬编码样式,直接利用Chakra主题的按钮变体:
修改CustomButton.tsx:
import React from 'react' import { Button } from '@chakra-ui/react' interface CustomButtonProps { children: React.ReactNode variant?: 'primary' | 'secondary' [key: string]: any } const CustomButton = ({ children, variant = 'primary', ...props }: CustomButtonProps) => { return ( <Button variant={variant} {...props}> {children} </Button> ) } export default CustomButton
内容的提问来源于stack exchange,提问作者Mahesh
相关产品推荐
相关产品推荐

