React中调用ThemeContext的toggleTheme时出现空函数问题
解决ThemeContext中toggleTheme函数为空的问题
问题原因
你的代码核心问题是App组件本身没有被ThemeContextProvider包裹。当你在App函数内调用useContext(ThemeContext)时,拿到的是createContext初始化时传入的默认值(也就是那个空的toggleTheme: () => {}),而非Provider提供的真实函数。因为ThemeContextProvider是在App的return语句里才渲染的,App组件自身不在Provider的作用范围内。
解决方案
提供两种可行的修复方式:
方式一:将Provider移到App组件外部
修改项目入口文件(通常是index.js),把ThemeContextProvider放在App外层:
import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import { ThemeContextProvider } from './theme/themeContext'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <ThemeContextProvider> <App /> </ThemeContextProvider> );
然后修改App.js,移除return里的ThemeContextProvider:
function App() { const { theme, toggleTheme } = useContext(ThemeContext); const handleClick = () => { console.log(theme); console.log(toggleTheme); toggleTheme(); }; return ( <AppContainer theme={theme}> <Button onClick={() => handleClick()}> Switch to {theme === "light" ? "Dark" : "Light"} </Button> {/* rest of your component code */} </AppContainer> ); }
方式二:拆分App内容为子组件
在App.js中创建一个子组件,让它被ThemeContextProvider包裹:
// 新增子组件Content function Content() { const { theme, toggleTheme } = useContext(ThemeContext); const handleClick = () => { console.log(theme); console.log(toggleTheme); toggleTheme(); }; return ( <AppContainer theme={theme}> <Button onClick={() => handleClick()}> Switch to {theme === "light" ? "Dark" : "Light"} </Button> {/* rest of your component code */} </AppContainer> ); } // 修改App组件 function App() { return ( <ThemeContextProvider> <Content /> </ThemeContextProvider> ); }
原理说明
只有被ThemeContext.Provider直接或间接包裹的组件,才能获取到Provider传递的上下文值。App组件本身如果在Provider外层,就只能拿到createContext的默认值;而子组件处于Provider内部时,就能正确获取到你定义的toggleTheme函数。
内容的提问来源于stack exchange,提问作者Alex Aung
相关产品推荐
相关产品推荐

