我正在尝试将基于函数的组件更改为基于类的组件。转换时出错。如何初始化类组件中的钩子。错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一:1.React和渲染器的版本可能不匹配(例如React DOM(2.你可能违反了胡克规则3.在同一应用中,您可能有多个React副本
这是我得到的错误
Papebase材料UI
import React from 'react';
import PropTypes from 'prop-types';
import { createMuiTheme, ThemeProvider, withStyles } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import Hidden from '@material-ui/core/Hidden';
import Typography from '@material-ui/core/Typography';
import Link from '@material-ui/core/Link';
import Navigator from '../Components/Navigator';
import Content from './Content';
import Header from '../Components/Header';
import { Switch, Route, BrowserRouter, Link as RouteLink } from "react-router-dom";
import { connect } from 'react-redux';
import { logout } from '../actions/auth';
function Copyright() {
return (
<Typography variant="body2" color="textSecondary" align="center">
{'Copyright © '}
<Link color="inherit" href="https://material-ui.com/">
Podo
</Link>{' '}
{new Date().getFullYear()}
{'.'}
</Typography>
);
}
let theme = createMuiTheme({
palette: {
primary: {
light: '#63ccff',
main: '#009be5',
dark: '#006db3',
},
},
typography: {
h5: {
fontWeight: 500,
fontSize: 26,
letterSpacing: 0.5,
},
},
shape: {
borderRadius: 8,
},
props: {
MuiTab: {
disableRipple: true,
},
},
mixins: {
toolbar: {
minHeight: 48,
},
},
});
theme = {
...theme,
overrides: {
MuiDrawer: {
paper: {
backgroundColor: '#18202c',
},
},
MuiButton: {
label: {
textTransform: 'none',
},
contained: {
boxShadow: 'none',
'&:active': {
boxShadow: 'none',
},
},
},
MuiTabs: {
root: {
marginLeft: theme.spacing(1),
},
indicator: {
height: 3,
borderTopLeftRadius: 3,
borderTopRightRadius: 3,
backgroundColor: theme.palette.common.white,
},
},
MuiTab: {
root: {
textTransform: 'none',
margin: '0 16px',
minWidth: 0,
padding: 0,
[theme.breakpoints.up('md')]: {
padding: 0,
minWidth: 0,
},
},
},
MuiIconButton: {
root: {
padding: theme.spacing(1),
},
},
MuiTooltip: {
tooltip: {
borderRadius: 4,
},
},
MuiDivider: {
root: {
backgroundColor: '#404854',
},
},
MuiListItemText: {
primary: {
fontWeight: theme.typography.fontWeightMedium,
},
},
MuiListItemIcon: {
root: {
color: 'inherit',
marginRight: 0,
'& svg': {
fontSize: 20,
},
},
},
MuiAvatar: {
root: {
width: 32,
height: 32,
},
},
},
};
const drawerWidth = 256;
const styles = {
root: {
display: 'flex',
minHeight: '100vh',
},
drawer: {
[theme.breakpoints.up('sm')]: {
width: drawerWidth,
flexShrink: 0,
},
},
app: {
flex: 1,
display: 'flex',
flexDirection: 'column',
},
main: {
flex: 1,
padding: theme.spacing(6, 4),
background: '#eaeff1',
},
footer: {
padding: theme.spacing(2),
background: '#eaeff1',
},
};
export class Paperbase extends React.Component {
render() {
const { classes } = this.props;
const [mobileOpen, setMobileOpen] = React.useState(false);
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen);
};
return (
<BrowserRouter>
<ThemeProvider theme={theme}>
<div className={classes.root}>
<CssBaseline />
<nav className={classes.drawer}>
<Hidden smUp implementation="js">
<Navigator
PaperProps={{ style: { width: drawerWidth } }}
variant="temporary"
open={mobileOpen}
onClose={handleDrawerToggle}
/>
</Hidden>
<Hidden xsDown implementation="css">
<Navigator PaperProps={{ style: { width: drawerWidth } }} />
</Hidden>
</nav>
<div className={classes.app}>
<Header onDrawerToggle={handleDrawerToggle} />
<main className={classes.main}>
<Switch>
<Route exact path="/dashboard/auth" render={() => <Content /> } />
<Route path="/Inbox" render={() => <div> Page inbox</div>} />
<Route path="/Starred" render={() => <div>PSage starred</div>} />
</Switch>
</main>
<footer className={classes.footer}>
<Copyright />
</footer>
</div>
</div>
</ThemeProvider>
</BrowserRouter>
)
}
}
Paperbase.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(Paperbase);
简短回答您不能在基于类的组件上使用react钩子。
稍长的答案:
引入钩子是为了允许在功能组件中使用状态。如果您使用的是类组件,那么操作状态的机制将内置到默认的类组件行为中。
所以在你的例子中,你想做一些类似的事情:
更换您的状态挂钩:
const [mobileOpen, setMobileOpen] = React.useState(false);
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen);
};
具有有状态类组件和setState()
:
class PaperBase extends React.Component {
constructor(props){
super(props);
this.state = {
mobileOpen: true,
}
this.handleDrawerToggle = this.handleDrawerToggle.bind(this);
}
handleDrawerToggle = () => {
let mobileOpen = this.state.mobileOpen;
mobileOpen != mobileOpen;
this.setState = {
mobileOpen: mobileOpen,
}
}
// ...
}
与其在这里解释它是如何工作的,我建议阅读关于组件中状态的官方教程:https://reactjs.org/docs/state-and-lifecycle.html