在基于类的组件中初始化react钩子

时间:2020-04-15 09:11:28

标签: reactjs react-redux material-ui

我正在尝试将基于功能的组件更改为基于类的组件。转换时出现错误。如何在类组件中初始化钩子。 错误:无效的挂钩调用。挂钩只能在功能组件的主体内部调用。可能由于以下原因之一而发生: 1.您的React和渲染器版本可能不匹配(例如React DOM) 2.您可能违反了《钩子规则》 3.您可能在同一应用程序中拥有多个React副本

This is the error I am getting

Papebase材质用户界面

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);

2 个答案:

答案 0 :(得分:2)

简短的答案,您不能在基于类的组件上使用react钩子。

答案 1 :(得分:0)

答案略长:

引入了挂钩,以允许在功能组件中使用状态。如果您使用的是类组件,则默认状态的类组件行为将内置处理状态的机制。

因此,在您的示例中,您想要执行以下操作:

替换状态钩子

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

,而不是在这里解释其工作原理。