【问题标题】:'Objects are not valid as a React child''对象作为 React 子级无效'
【发布时间】:2020-01-20 05:23:36
【问题描述】:

我不明白为什么会出现以下错误。 我正在尝试在返回函数中呈现 {links}、{collapse},但它不起作用。 链接和折叠是关于打开子菜单。 感谢您的帮助。

错误信息:

对象作为 React 子对象无效(找到:带键的对象 {$$typeof, type, compare, displayName, muiName})。如果你打算 渲染一组孩子,使用数组代替。

-- Sidebar.js

/*eslint-disable*/
import React from "react";
import classNames from "classnames";
import PropTypes from "prop-types";
import { NavLink } from "react-router-dom";
// @material-ui/core components
import { makeStyles } from "@material-ui/core/styles";
import {
  Drawer,
  Hidden,
  List,
  ListItem,
  ListItemText,
  Icon,
  Collapse
} from "@material-ui/core";
import ExpandLess from "@material-ui/icons/ExpandLess";
import ExpandMore from "@material-ui/icons/ExpandMore";
import ListItemLink from "./ListItemLink";

// core components
import AdminNavbarLinks from "components/Navbars/AdminNavbarLinks.js";
import RTLNavbarLinks from "components/Navbars/RTLNavbarLinks.js";

import styles from "assets/jss/material-dashboard-react/components/sidebarStyle.js";

const useStyles = makeStyles(styles);

export default function Sidebar(props) {
  const classes = useStyles();
  // verifies if routeName is the one active (in browser input)
  function activeRoute(routeName) {
    return window.location.href.indexOf(routeName) > -1 ? true : false;
  }
  const { color, logo, image, logoText, routes } = props;
  const [open, setOpen] = React.useState(true);

  const handleClick = () => {
    setOpen(!open);
  };

  var links = (
    <div>
      {routes.map((prop, key) => {
        return (
          <div>
            {prop.submenu.length > 0 ? (
              <ListItemLink
                to={prop.layout + prop.path}
                key={prop.id}
                menuText={prop.name}
                onClick={handleClick}
                subOpen={open}
                icon={prop.icon}
              />
            ) : (
              <ListItemLink
                to={prop.layout + prop.path}
                key={prop.id}
                menuText={prop.name}
                icon={prop.icon}
              />
            )}
          </div>
        );
      })}
    </div>
  );

  var collapse = (
    <Collapse in={open} timeout="auto" unmountOnExit>
      <List component="div" disablePadding>
        {routes.map((prop, key) => {
          {
            prop.submenu.map((sub, index) => {
              return (
                <ListItemLink
                  key={sub.id}
                  to={sub.path}
                  menuText={sub.name}
                  icon={sub.icon}
                  className={classes.nested}
                />
              );
            });
          }
        })}
      </List>
    </Collapse>
  );

  var brand = (
    <div className={classes.logo}>
      <a
        className={classNames(classes.logoLink, {
          [classes.logoLinkRTL]: props.rtlActive
        })}
        target="_blank"
      >
        <div className={classes.logoImage}>
          <img src={logo} alt="logo" className={classes.img} />
        </div>
        {logoText}
      </a>
    </div>
  );

  return (
    <div>
      <Hidden mdUp implementation="css">
        <Drawer
          variant="temporary"
          anchor={props.rtlActive ? "left" : "right"}
          open={props.open}
          classes={{
            paper: classNames(classes.drawerPaper, {
              [classes.drawerPaperRTL]: props.rtlActive
            })
          }}
          onClose={props.handleDrawerToggle}
          ModalProps={{
            keepMounted: true // Better open performance on mobile.
          }}
        >
          {brand}
          <div className={classes.sidebarWrapper}>
            {props.rtlActive ? <RTLNavbarLinks /> : <AdminNavbarLinks />}
            <List component="nav" className={classes.list}>
              {links}
              {collapse}
            </List>
          </div>
          {image !== undefined ? (
            <div
              className={classes.background}
              style={{ backgroundImage: "url(" + image + ")" }}
            />
          ) : null}
        </Drawer>
      </Hidden>
      <Hidden smDown implementation="css">
        <Drawer
          anchor={props.rtlActive ? "right" : "left"}
          variant="permanent"
          open
          classes={{
            paper: classNames(classes.drawerPaper, {
              [classes.drawerPaperRTL]: props.rtlActive
            })
          }}
        >
          {brand}
          <div className={classes.sidebarWrapper}>
            <List component="nav" className={classes.list}>
              {links}
              {collapse}
            </List>
          </div>
          {image !== undefined ? (
            <div
              className={classes.background}
              style={{ backgroundImage: "url(" + image + ")" }}
            />
          ) : null}
        </Drawer>
      </Hidden>
    </div>
  );
}

Sidebar.propTypes = {
  rtlActive: PropTypes.bool,
  handleDrawerToggle: PropTypes.func,
  bgColor: PropTypes.oneOf(["purple", "blue", "green", "orange", "red"]),
  logo: PropTypes.string,
  image: PropTypes.string,
  logoText: PropTypes.string,
  routes: PropTypes.arrayOf(PropTypes.object),
  open: PropTypes.bool
};

-- ListItemLink.js

import React from "react";
import { ListItem, ListItemText, ListItemIcon } from "@material-ui/core";
import ExpandLess from "@material-ui/icons/ExpandLess";
import ExpandMore from "@material-ui/icons/ExpandMore";
import { PropTypes } from "prop-types";
import { Link as RouterLink } from "react-router-dom";

function ListItemLink(props) {
  const { to, menuText, icon, subOpen, ...other } = props;

  return (
    <ListItem button component={RouterLink} to={to} {...other}>
      <ListItemIcon>{icon}</ListItemIcon>
      <ListItemText primary={menuText} />
      {subOpen != null ? subOpen ? <ExpandLess /> : <ExpandMore /> : null}
    </ListItem>
  );
}

ListItemLink.propTypes = {
  subOpen: PropTypes.bool,
  to: PropTypes.string.isRequired
};

export default ListItemLink;

【问题讨论】:

  • prop.icon 中有什么?
  • 错误具体来自哪里,你缩小范围了吗?另外,brand 是什么,也直接渲染为子级
  • 你可以制作一个可行的 fiddle 或 stackblitz 示例,这样我们就可以轻松地寻找 bug。
  • {brand} 对象是什么?
  • @CampbellMG 它有一个图标组件。

标签: javascript reactjs


【解决方案1】:

collapse 中,您有两个map 函数。你应该返回第二个map 函数。

类似这样的:

const collapse = (
  <Collapse in={open} timeout="auto" unmountOnExit>
    <List component="div" disablePadding>
      {routes.map((prop, key) => {
        return prop.submenu.map((sub, index) => {
          return (
            <ListItemLink
              key={sub.id}
              to={sub.path}
              menuText={sub.name}
              icon={sub.icon}
              className={classes.nested}
            />
          );
        });
      })}
    </List>
  </Collapse>
);

【讨论】:

  • 需要返回map,否则你只是显示map函数是什么而不是返回什么
【解决方案2】:

我解决了我的问题如下: 我想我返回了错误的对象...

<List
  {...rest}
  className={clsx(classes.root, className)}
>
  {pages.map(page => (
    <React.Fragment key={page.title}>
      <ListItem
        className={classes.item}
        disableGutters
        key={page.title}
        onClick={page.submenu.length > 0 ? handleClick : null}
        open={page.submenu.length > 0 ? open : null}
      >
      <Button
        activeClassName={classes.active}
        className={classes.button}
        component={CustomRouterLink}
        to={page.href}
      >
      <div className={classes.icon}>{page.icon}</div>
      {page.title}
      {page.submenu.length > 0 ? (
          open ? (
            <ExpandLess />
          ) : (
            <ExpandMore />
          )
        ) : null}
      </Button>
      </ListItem>
      <Collapse in={open} timeout={100} unmountOnExit>
      <List component="div" disablePadding>
        {page.submenu.map((sub, index) => {
          return (
            <React.Fragment key={sub.title}>
              <ListItem
                className={classes.nested}
                disableGutters
                key={sub.title}
              >
              <Button
                activeClassName={classes.active}
                className={classes.button}
                component={CustomRouterLink}
                to={sub.href}
              >
                <div className={classes.icon}>{sub.icon}</div>
                {sub.title}
                </Button>
              </ListItem>
            </React.Fragment>
          );
        })}
      </List>
      </Collapse>
    </React.Fragment>
  ))}
</List>

【讨论】:

    猜你喜欢
    • 2020-03-26
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 2017-05-27
    相关资源
    最近更新 更多