亲爱的
我正在尝试编写来自Material-Ui和react-intl的不同HOC,但这失败了>
我尝试过
export default compose(
withStyles(styles),
withWidth(),
)(injectIntl(NavBar));
和
export default compose(
withStyles(styles),
withWidth(),
injectIntl(),
)(NavBar);
第一种方法,我从 babel
收到错误消息TypeError: Cannot call a class as a function
_classCallCheck
D:/ANDROID_APPS/REACT/MATERIALZE-UI/CODE/materialui-sandbox/client/node_modules/@material-ui/core/node_modules/@babel/runtime/helpers/classCallCheck.js:3
1 | function _classCallCheck(instance, Constructor) {
2 | if (!(instance instanceof Constructor)) {
> 3 | throw new TypeError("Cannot call a class as a function");
第二种方法,我从 react-intl:
收到错误消息TypeError: Cannot read property 'displayName' of undefined
getDisplayName
D:/ANDROID_APPS/REACT/MATERIALZE-UI/CODE/materialui-sandbox/client/node_modules/react-intl/lib/index.es.js:679
676 |
677 |
678 | function getDisplayName(Component$$1) {
> 679 | return Component$$1.displayName || Component$$1.name || 'Component';
680 | }
681 |
682 | function injectIntl(WrappedComponent) {
导航栏组件(对不起,大个子) 无需使用Compose,就可以使用。 但是应用compose失败
请注意如何将styles
对象传递给withWidth
而不是withStyles
。传递给withStyle会引发错误
import { Hidden, withWidth } from "@material-ui/core";
import AppBar from "@material-ui/core/AppBar";
import Avatar from "@material-ui/core/Avatar";
import Button from "@material-ui/core/Button";
import Chip from "@material-ui/core/Chip";
import Divider from "@material-ui/core/Divider";
import IconButton from "@material-ui/core/IconButton";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import { withStyles } from "@material-ui/core/styles";
import SwipeableDrawer from "@material-ui/core/SwipeableDrawer";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import MailIcon from "@material-ui/icons/Mail";
import MenuIcon from "@material-ui/icons/Menu";
import InboxIcon from "@material-ui/icons/MoveToInbox";
import PropTypes from "prop-types";
import React, { Fragment, useContext, useState } from "react";
import { FormattedMessage, injectIntl, intlShape } from "react-intl";
import { Link } from "react-router-dom";
import { getInitials } from "../../../helpers/genericFuncs";
import { ContextState } from "../../../stateManagment";
import Colors from "../colors";
import logoDWP from "../img/logoDWP.png";
const drawerWidth = 250;
const styles = theme => ({
appBar: {
zIndex: theme.zIndex.drawer + 1,
},
drawer: {
width: drawerWidth,
},
drawerPaper: {
width: drawerWidth,
},
toolbar: {
mixins: theme.mixins.toolbar,
},
});
const handleProfilClick = () => alert("You clicked the Chip."); // eslint-disable-line no-alert
const NavBar = props => {
const { classes, intl } = props;
const initialState = {
isOpened: false,
};
const [localstate, setState] = useState(initialState);
const state = useContext(ContextState);
const { isAuthenticated } = state.auth;
const { firstname, lastname } = state.user;
const toggleDrawer = isOpened => () => {
setState({ isOpened });
};
const MenuList = (
<div className={classes.toolbar}>
<List>
{!isAuthenticated ? (
<Fragment>
<Button color="inherit" component={Link} to="/signup">
<FormattedMessage id="nav.signup" defaultMessage="Sign Up" />
</Button>
<Button color="inherit" component={Link} to="/login">
<FormattedMessage id="nav.signin" defaultMessage="Sign In" />
</Button>
</Fragment>
) : (
<Fragment>
<Chip
style={{ background: Colors.chips.chipsBG }}
avatar={
<Avatar style={{ background: Colors.chips.avatarBG }}>
{getInitials(firstname, lastname)}
</Avatar>
}
label={intl.formatMessage({ id: "nav.chipmenu" })}
onClick={handleProfilClick}
/>
<List>
{["Mon Profil", "DashBoard", "Creer Groupe"].map(
(text, index) => (
<ListItem button key={text}>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
),
)}
</List>
<Divider />
<List>
{["Nous contacter"].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
<Button color="inherit" component={Link} to="/tablepage">
<FormattedMessage id="nav.reporting" defaultMessage="Reporting" />
</Button>
<Button color="inherit" component={Link} to="/charts">
<FormattedMessage id="nav.charts" defaultMessage="Charts" />
</Button>
<Button color="inherit" component={Link} to="/logout">
<FormattedMessage id="nav.signout" defaultMessage="Sign Out" />
</Button>
</Fragment>
)}
</List>
</div>
);
return (
<div>
<AppBar position="sticky" className={classes.appBar}>
<Toolbar className={classes.toolbar}>
<Hidden smUp>
<IconButton
color="inherit"
aria-label="Menu"
onClick={toggleDrawer(!localstate.isOpened)}
>
<MenuIcon />
</IconButton>
</Hidden>
<Typography variant="h6" color="inherit" style={{ flexGrow: 1 }}>
<img src={logoDWP} alt="" height="50" width="50" />
</Typography>
<Hidden smDown>
{!isAuthenticated ? (
<Fragment>
<Button color="inherit" component={Link} to="/signup">
<FormattedMessage id="nav.signup" defaultMessage="SignUp" />
</Button>
<Button color="inherit" component={Link} to="/login">
<FormattedMessage id="nav.signin" defaultMessage="Sign In" />
</Button>
</Fragment>
) : (
<>
<Chip
style={{ background: Colors.chips.chipsBG }}
avatar={
<Avatar style={{ background: Colors.chips.avatarBG }}>
{getInitials(firstname, lastname)}
</Avatar>
}
label={intl.formatMessage({
id: "nav.chipmenu",
})}
onClick={handleProfilClick}
/>
<Button color="inherit" component={Link} to="/tablepage">
<FormattedMessage
id="nav.reporting"
defaultMessage="Reporting"
/>
</Button>
<Button color="inherit" component={Link} to="/charts">
<FormattedMessage id="nav.charts" defaultMessage="Charts" />
</Button>
<Button color="inherit" component={Link} to="/logout">
<FormattedMessage
id="nav.signout"
defaultMessage="Sign Out"
/>
</Button>
</>
)}
</Hidden>
</Toolbar>
</AppBar>
<SwipeableDrawer
anchor="left"
open={localstate.isOpened}
onClose={toggleDrawer(localstate.isOpened)}
onOpen={toggleDrawer(!localstate.isOpened)}
className={classes.drawer}
classes={{ paper: classes.drawerPaper }}
>
<div
tabIndex={0}
role="button"
onClick={toggleDrawer(!localstate.isOpened)}
onKeyDown={toggleDrawer(!localstate.isOpened)}
className={classes.toolbar}
>
{MenuList}
</div>
</SwipeableDrawer>
</div>
);
};
NavBar.propTypes = {
classes: PropTypes.objectOf(PropTypes.any).isRequired,
intl: intlShape.isRequired,
};
export default withStyles(withWidth(styles))(injectIntl(NavBar));
任何帮助将不胜感激。
答案 0 :(得分:1)
我成功使用了您列出的第一种方法,因此我认为您可能未包含代码或配置中的某些问题。问题可能在NavBar
内部。
这是一个可行的示例:
import React from "react";
import ReactDOM from "react-dom";
import { withStyles } from "@material-ui/core/styles";
import withWidth from "@material-ui/core/withWidth";
import { compose } from "recompose";
import { IntlProvider, injectIntl } from "react-intl";
const styles = theme => ({
root: {
height: 100,
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
maxWidth: "90vw"
}
});
function App(props) {
return (
<div className={props.classes.root}>
Width: {props.width}
<br />
Date: {props.intl.formatDate(new Date())}
</div>
);
}
const StyledApp = compose(
withStyles(styles),
withWidth()
)(injectIntl(App));
const rootElement = document.getElementById("root");
ReactDOM.render(
<IntlProvider>
<StyledApp />
</IntlProvider>,
rootElement
);