如何解决Chakra UI中Switch组件无法切换颜色模式的问题?
问题原因及修复方案
你代码中的核心问题是useColorMode hook的调用位置不符合Chakra UI的上下文规则,同时缺少必要的初始化配置,按以下步骤修改即可:
- 1. 调整ChakraProvider的渲染层级
useColorMode必须在ChakraProvider包裹的子组件内部调用,你当前在App组件内调用hook,同时在App的返回值里才渲染ChakraProvider,相当于在上下文作用域外调用hook,toggle操作不会生效。
正确做法是将ChakraProvider移到入口文件(如main.tsx/index.tsx)中,包裹整个App组件,同时添加ColorModeScript完成颜色模式初始化:
import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import { ChakraProvider, ColorModeScript } from '@chakra-ui/react' import customTheme from './theme' const root = ReactDOM.createRoot(document.getElementById('root')!) root.render( <React.StrictMode> <ColorModeScript initialColorMode={customTheme.config.initialColorMode} /> <ChakraProvider theme={customTheme}> <App /> </ChakraProvider> </React.StrictMode>, )
- 2. 修改App组件代码
移除App组件内部的ChakraProvider,现在hook可以拿到正确的上下文:
import * as React from "react" import { Box, FormControl, FormLabel, Switch, useColorMode, useColorModeValue } from "@chakra-ui/react" import "@fontsource/spartan/700.css" const darkSaturatedBlue = { mainBackgroundColor:"hsl(222, 26%, 31%)", toggleKeybadBackgroundColor:"hsl(223, 31%, 20%)", screenBackgroundColor:"hsl(224, 36%, 15%)", buttonDigitColor:"hsl(221, 14%, 31%)", } export default function App(){ const {toggleColorMode} = useColorMode(); const bg = useColorModeValue("red.500",darkSaturatedBlue.mainBackgroundColor); const color = useColorModeValue("white","gray.800"); return ( <Box bg={bg} h="100vh" w="100vw" color={color}> <Box mx="auto" w={["100%",375]}> <Box> <FormControl display="flex" alignItems="center"> <FormLabel htmlFor="theme-switch" mb="0" fontSize="9"> THEME </FormLabel> <Switch id="theme-switch" size="sm" onChange={toggleColorMode} /> </FormControl> </Box> </Box> </Box> ); }
- 3. 可选配置调整
如果你不需要自动跟随系统颜色模式,可将主题配置中的useSystemColorMode改为false,避免用户手动切换后被系统主题覆盖。
内容的提问来源于stack exchange,提问作者Esam Olwan
相关产品推荐
相关产品推荐

