无法撰写withStyle,withWidth和injectIntl​​

时间:2019-01-30 14:58:50

标签: reactjs material-ui react-intl compose

亲爱的

我正在尝试编写来自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));

任何帮助将不胜感激。

1 个答案:

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

Edit compose mutliple HOC