React 深色主题:从 useContext 访问时 setContext 不是函数
React dark theme: setContext is not a function when accessing from useContext
我似乎看不出这里出了什么问题,useContext 和 useState 挂钩的基本用法。我有一个 darkModeContext,我实际上只是翻转 darkMode 的布尔值,但是在尝试为上下文翻转它时我得到 setContext 不是函数。
我从 navDrawer 中取出了一些代码以使其更易于查看,但这是我在处理代码时遇到的错误:
DarkThemeContext.js
import React from "react";
const DarkThemeContext = React.createContext({
darkMode: false,
setDarkMode:() => {},
});
export default DarkThemeContext
DarkThemeSwitcher.js
import React, { useContext } from 'react';
import { IconButton, Tooltip } from '@material-ui/core';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import LightThemeIcon from '@material-ui/icons/Brightness7';
import DarkThemeIcon from '@material-ui/icons/Brightness4';
import DarkThemeContext from '../DarkThemeContext/DarkThemeContext';
const DarkThemeSwitcher = () => {
const useStyles = makeStyles((theme) => ({
darkThemeButton: {
background: "none",
border: "none",
},
darkThemeMobileButton: {
[theme.breakpoints.up('sm')]: {
display: "none",
},
[theme.breakpoints.down('sm')]: {
background: "none",
border: "none",
display: "visible",
paddingLeft: theme.spacing(2),
minWidth: '25%'
},
},
menuHeaderText: {
minWidth: '97%',
}
}));
const classes = useStyles();
const { darkMode, setDarkMode } = useContext(DarkThemeContext);
const handleLightThemeToggle = () => {
console.log(!darkMode)
setDarkMode(!darkMode);
};
return (
darkMode ?
<Tooltip title="Light Mode" className={classes.darkThemeMobileButton} onClick={handleLightThemeToggle} >
<IconButton aria-label="Light Mode">
<DarkThemeIcon />
</IconButton>
</Tooltip >
:
<Tooltip title="Dark Mode" className={classes.darkThemeMobileButton} onClick={handleLightThemeToggle} >
<IconButton aria-label="Dark Mode">
<LightThemeIcon />
</IconButton>
</Tooltip>
)
}
export default DarkThemeSwitcher;
NavDrawer.js
import React from 'react';
import DarkThemeContext from '../DarkThemeContext/DarkThemeContext';
import DarkThemeSwitcher from '../DarkThemeSwitcher/DarkThemeSwitcher';
const NavDrawer = ({ children, window }) => {
const classes = useStyles();
const theme = useTheme();
const [mobileOpen, setMobileOpen] = React.useState(false);
const [darkTheme, setDarkTheme] = React.useState(false);
const value = { darkTheme, setDarkTheme };
const container = window !== undefined ? () => window().document.body : undefined;
return (
<DarkThemeContext.Provider value={value}>
<ThemeProvider theme={darkThemeStyling}>
<div className={classes.root}>
<CssBaseline />
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
edge="start"
onClick={handleDrawerToggle}
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
<Typography className={classes.menuHeaderText} variant="h6" noWrap>
My app
</Typography>
<DarkThemeSwitcher/>
</Toolbar>
</AppBar>
<nav className={classes.drawer} aria-label="navigation links">
<Hidden smUp implementation="css">
<SwipeableDrawer
container={container}
variant="temporary"
anchor={theme.direction === 'rtl' ? 'right' : 'left'}
open={mobileOpen}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper,
}}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawer}
</SwipeableDrawer>
</Hidden>
<Hidden xsDown implementation="css">
<Drawer
classes={{
paper: classes.drawerPaper,
}}
variant="permanent"
open
>
{drawer}
</Drawer>
</Hidden>
</nav>
<main className={classes.content}>
<div className={classes.toolbar} />
{children}
{console.log(value)}
</main>
</div>
</ThemeProvider>
</DarkThemeContext.Provider>
);
}
export default NavDrawer;
初始化值时,DarkThemeContext
和 NavDrawer
中有不同的键,即 darkTheme
与 darkMode
。
在 NavDrawer
中重命名应该可以解决错误。
// In NavDrawer
const [darkMode, setDarkMode] = React.useState(false);
const value = { darkMode, setDarkMode };
我似乎看不出这里出了什么问题,useContext 和 useState 挂钩的基本用法。我有一个 darkModeContext,我实际上只是翻转 darkMode 的布尔值,但是在尝试为上下文翻转它时我得到 setContext 不是函数。
我从 navDrawer 中取出了一些代码以使其更易于查看,但这是我在处理代码时遇到的错误:
DarkThemeContext.js
import React from "react";
const DarkThemeContext = React.createContext({
darkMode: false,
setDarkMode:() => {},
});
export default DarkThemeContext
DarkThemeSwitcher.js
import React, { useContext } from 'react';
import { IconButton, Tooltip } from '@material-ui/core';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import LightThemeIcon from '@material-ui/icons/Brightness7';
import DarkThemeIcon from '@material-ui/icons/Brightness4';
import DarkThemeContext from '../DarkThemeContext/DarkThemeContext';
const DarkThemeSwitcher = () => {
const useStyles = makeStyles((theme) => ({
darkThemeButton: {
background: "none",
border: "none",
},
darkThemeMobileButton: {
[theme.breakpoints.up('sm')]: {
display: "none",
},
[theme.breakpoints.down('sm')]: {
background: "none",
border: "none",
display: "visible",
paddingLeft: theme.spacing(2),
minWidth: '25%'
},
},
menuHeaderText: {
minWidth: '97%',
}
}));
const classes = useStyles();
const { darkMode, setDarkMode } = useContext(DarkThemeContext);
const handleLightThemeToggle = () => {
console.log(!darkMode)
setDarkMode(!darkMode);
};
return (
darkMode ?
<Tooltip title="Light Mode" className={classes.darkThemeMobileButton} onClick={handleLightThemeToggle} >
<IconButton aria-label="Light Mode">
<DarkThemeIcon />
</IconButton>
</Tooltip >
:
<Tooltip title="Dark Mode" className={classes.darkThemeMobileButton} onClick={handleLightThemeToggle} >
<IconButton aria-label="Dark Mode">
<LightThemeIcon />
</IconButton>
</Tooltip>
)
}
export default DarkThemeSwitcher;
NavDrawer.js
import React from 'react';
import DarkThemeContext from '../DarkThemeContext/DarkThemeContext';
import DarkThemeSwitcher from '../DarkThemeSwitcher/DarkThemeSwitcher';
const NavDrawer = ({ children, window }) => {
const classes = useStyles();
const theme = useTheme();
const [mobileOpen, setMobileOpen] = React.useState(false);
const [darkTheme, setDarkTheme] = React.useState(false);
const value = { darkTheme, setDarkTheme };
const container = window !== undefined ? () => window().document.body : undefined;
return (
<DarkThemeContext.Provider value={value}>
<ThemeProvider theme={darkThemeStyling}>
<div className={classes.root}>
<CssBaseline />
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
edge="start"
onClick={handleDrawerToggle}
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
<Typography className={classes.menuHeaderText} variant="h6" noWrap>
My app
</Typography>
<DarkThemeSwitcher/>
</Toolbar>
</AppBar>
<nav className={classes.drawer} aria-label="navigation links">
<Hidden smUp implementation="css">
<SwipeableDrawer
container={container}
variant="temporary"
anchor={theme.direction === 'rtl' ? 'right' : 'left'}
open={mobileOpen}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper,
}}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawer}
</SwipeableDrawer>
</Hidden>
<Hidden xsDown implementation="css">
<Drawer
classes={{
paper: classes.drawerPaper,
}}
variant="permanent"
open
>
{drawer}
</Drawer>
</Hidden>
</nav>
<main className={classes.content}>
<div className={classes.toolbar} />
{children}
{console.log(value)}
</main>
</div>
</ThemeProvider>
</DarkThemeContext.Provider>
);
}
export default NavDrawer;
初始化值时,DarkThemeContext
和 NavDrawer
中有不同的键,即 darkTheme
与 darkMode
。
在 NavDrawer
中重命名应该可以解决错误。
// In NavDrawer
const [darkMode, setDarkMode] = React.useState(false);
const value = { darkMode, setDarkMode };