【问题标题】:Adding new page to reactjs template将新页面添加到 reactjs 模板
【发布时间】:2018-04-09 08:36:01
【问题描述】:

我目前正在学习 reactjs 以创建一个小型应用程序
所以我从 github 下载了this template 并开始探索它以了解 reactjs 是如何工作的。

后来我想在同一个模板下创建一个登录页面 所以这就是我所做的:
在视图下,我在登录文件夹中创建了新页面 Login.jsx
路径:views/Login/Login.jsx

import React from "react";
import { Grid } from "material-ui";

import {
  ItemGrid
} from "components";

function Login({ ...props }) {
  return (
    <div>
      <Grid container>
        <ItemGrid xs={12} sm={12} md={4}>
          test loginpage
        </ItemGrid>
      </Grid>
    </div>
  );
}

export default Login;

然后我将它导入 app.jsx 并在 appRoutes 下创建了一个新路由

路径:routes/app.jsx

const appRoutes = [
  {
    path: "/login",
    component: LoginPage,
  },
 ....
]

然后我对主容器 App.jsx 进行了此更改:
路径:containers/App/App.jsx
我创建了一个方法 getLogin

getLogin() {
  return this.props.location.pathname !== "/login";
}

我变了

<Sidebar
    routes={appRoutes}
  logoText={"RecBot Cpanel"}
  logo={logo}
  image={image}
  handleDrawerToggle={this.handleDrawerToggle}
  open={this.state.mobileOpen}
  color="blue"
  {...rest}
/>

进入这个

{this.getLogin() ? (
  <Sidebar
    routes={appRoutes}
    logoText={"RecBot Cpanel"}
    logo={logo}
    image={image}
    handleDrawerToggle={this.handleDrawerToggle}
    open={this.state.mobileOpen}
    color="blue"
    {...rest}
  />

) : (
    <div></div>
  )}

为了隐藏侧边栏在登录页面中显示。

最后,当我尝试运行该应用程序时,登录页面可以正常工作,但在任何其他路线中我都收到此错误:

元素类型无效:应为字符串(用于内置组件) 或类/函数(用于复合组件)但得到:未定义。你 可能忘记从定义它的文件中导出您的组件, 或者您可能混淆了默认导入和命名导入。

查看Sidebar的渲染方法。

这是侧边栏组件:

import React from "react";
import PropTypes from "prop-types";
import { NavLink } from "react-router-dom";
import cx from "classnames";
import {
  withStyles,
  Drawer,
  Hidden,
  List,
  ListItem,
  ListItemIcon,
  ListItemText
} from "material-ui";

import { HeaderLinks } from "components";

import sidebarStyle from "variables/styles/sidebarStyle.jsx";

const Sidebar = ({ ...props }) => {
  // verifies if routeName is the one active (in browser input)
  function activeRoute(routeName) {
    return props.location.pathname.indexOf(routeName) > -1 ? true : false;
  }
  const { classes, color, logo, image, logoText, routes } = props;
  var links = (
    <List className={classes.list}>
      {routes.map((prop, key) => {
        if (prop.redirect) return null;
        const listItemClasses = cx({
          [" " + classes[color]]: activeRoute(prop.path)
        });
        const whiteFontClasses = cx({
          [" " + classes.whiteFont]: activeRoute(prop.path)
        });
        return (
          <NavLink
            to={prop.path}
            className={classes.item}
            activeClassName="active"
            key={key}
          >
            <ListItem button className={classes.itemLink + listItemClasses}>
              <ListItemIcon className={classes.itemIcon + whiteFontClasses}>
                <prop.icon />
              </ListItemIcon>
              <ListItemText
                primary={prop.sidebarName}
                className={classes.itemText + whiteFontClasses}
                disableTypography={true}
              />
            </ListItem>
          </NavLink>
        );
      })}
    </List>
  );
  var brand = (
    <div className={classes.logo}>
      <a href="https://www.creative-tim.com" className={classes.logoLink}>
        <div className={classes.logoImage}>
          <img src={logo} alt="logo" className={classes.img} />
        </div>
        {logoText}
      </a>
    </div>
  );
  return (
    <div>
      <Hidden mdUp>
        <Drawer
          variant="temporary"
          anchor="right"
          open={props.open}
          classes={{
            paper: classes.drawerPaper
          }}
          onClose={props.handleDrawerToggle}
          ModalProps={{
            keepMounted: true // Better open performance on mobile.
          }}
        >
          {brand}
          <div className={classes.sidebarWrapper}>
            <HeaderLinks />
            {links}
          </div>
          {image !== undefined ? (
            <div
              className={classes.background}
              style={{ backgroundImage: "url(" + image + ")" }}
            />
          ) : null}
        </Drawer>
      </Hidden>
      <Hidden smDown>
        <Drawer
          anchor="left"
          variant="permanent"
          open
          classes={{
            paper: classes.drawerPaper
          }}
        >
          {brand}
          <div className={classes.sidebarWrapper}>{links}</div>
          {image !== undefined ? (
            <div
              className={classes.background}
              style={{ backgroundImage: "url(" + image + ")" }}
            />
          ) : null}
        </Drawer>
      </Hidden>
    </div>
  );
};

Sidebar.propTypes = {
  classes: PropTypes.object.isRequired
};

export default withStyles(sidebarStyle)(Sidebar);

我做错了什么?

【问题讨论】:

  • 请分享Sidebar渲染方法,问题好像出在那儿
  • @ArnoldGandarillas 完成
  • import { HeaderLinks } from "components" 你有 components 作为 webpack 的别名吗?
  • @ArnoldGandarrilas yes ofc ,模板一开始工作得很好
  • 是的,我看到了。另一件事,您的路由数组对象中是否有 icon 属性?如果不删除 &lt;prop.icon /&gt; 看看会发生什么。

标签: javascript reactjs


【解决方案1】:

您需要做的是检查icon 是否存在于您的prop 对象中

{prop.icon && <prop.icon />}

这样,如果图标存在,您将保留它们,如果不存在,则避免错误。

您可以查看此page 以了解有关 React 中条件渲染的更多信息。

【讨论】:

  • 完美!谢谢 。只是我需要扭曲整个ListItemIcon,因为我得到 TypeError: Cannot read property 'props' of undefined
猜你喜欢
  • 2016-05-02
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 2021-04-29
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多