【问题标题】:Error: Objects are not valid as a React child - Unhandled Runtime Error错误:对象作为 React 子项无效 - 未处理的运行时错误
【发布时间】:2022-02-04 07:59:00
【问题描述】:

我一直在尝试使用在building a 'Strip' style menu 上找到的教程文章创建导航栏。这对我来说是一次学习经历,因为我还在学习 React、NextJs 和 TypeScript。

在对以前的问题获得一些帮助后,我现在又遇到了两个问题:

  1. 对象错误(主要问题)

当我将鼠标悬停在菜单项上时出现渲染问题。如果我在 MenuItem.tsx 中注释掉 {isBeingHovered && <SubItemContainer>{children}</SubItemContainer>},我可以悬停主菜单项,但子菜单项显然没有显示。当我不处理子菜单项时,非常基本的功能似乎可以工作。但是,一旦将上述行放回代码中,我就会收到以下错误

错误:对象作为 React 子对象无效(找到:带有键 {title, text} 的对象)。如果您打算渲染一组子项,请改用数组。

  1. Hashicon 值错误

在 navbarType.ts 中设置 SubMenuItem.tsx 的道具后,我仍然收到<Hashicon value={title} size={25} /> 中的“值”错误。我的一部分认为这可能是由于 Hashicon 看起来有点过时了(看起来它最近一次更新是在 2 年前),因为我提到我还是新手,错误仍然很容易出现在键盘和椅子之间.我的错误是

没有重载匹配这个调用。重载 1 of 2, '(props: Props | 只读):Hashicon',给出了以下错误。 类型“PropsWithChildren”不可分配给类型“字符串”。重载 2 of 2, '(props: Props, context: any): Hashicon', 给出了以下错误。 类型“PropsWithChildren”不可分配给类型“字符串”。

非常感谢您对此提供的任何帮助、见解或建议。如果我将其分解为太多的组成部分,我欢迎任何建议。我已经去并附上了下面的当前代码。

Navbar.tsx

import MenuItem from "./MenuItem";
import { motion } from "framer-motion";
import SubMenuItem from "./SubMenuItem";

const Navbar = () => {
  return (
    <div className="w-screen">
      <motion.div className="flex justify-center p-10">
        <MenuItem text={"Home"} style={{}}>
          <SubMenuItem title="Product" text="A SaaS for e-commerce" />
          <SubMenuItem title="Blog" text="Latest posts" />
          <SubMenuItem title="Contact" text="Get in touch" />
        </MenuItem>
        <MenuItem text={"About"} style={{ minWidth: 400 }}>
          <SubMenuItem title="The Team" text="Get to know us better" />
          <SubMenuItem title="The Company" text="Since 1998" />
          <SubMenuItem
            title="Our Mission"
            text="Increase the GDP of the internet"
          />
          <SubMenuItem title="Investors" text="who's backing us" />
        </MenuItem>
        <MenuItem text={"Products"} style={{ minWidth: 400 }}>
          <SubMenuItem
            title="Ecommerce"
            text="Unify online and in-person payments"
          />
          <SubMenuItem
            title="Marketplaces"
            text="Pay out globally and facilitate multiparty payments"
          />
          <SubMenuItem
            title="Platforms"
            text="Let customers accept payments within your platform"
          />
          <SubMenuItem
            title="Creator Economy"
            text="Facilitate on-platform payments and pay creators globally"
          />
        </MenuItem>
      </motion.div>
    </div>
  );
};

export default Navbar;

MenuItem.tsx

import { FunctionComponent } from "react";
import { motion } from "framer-motion";
import { useState } from "react";
import Underline from "./Underline";
import SubItemContainer from "./SubItemContainer";
import { IMenuItem } from "../../navbarType";

const MenuItem: FunctionComponent<IMenuItem> = ({ text, children }) => {
  const [isBeingHovered, setIsBeingHovered] = useState(false);

  return (
    <motion.div
      className="relative px-10 cursor-pointer"
      onHoverStart={() => setIsBeingHovered(true)}
      onHoverEnd={() => setIsBeingHovered(false)}
    >
      <span className="relative">
        {text}
        {isBeingHovered && <Underline />}
      </span>
      {isBeingHovered && <SubItemContainer>{children}</SubItemContainer>}
    </motion.div>
  );
};

export default MenuItem;

SubItemContainer.tsx

import { motion } from "framer-motion";
import { FunctionComponent } from "react";

const SubItemContainer: FunctionComponent = ({ children }) => {
  return (
    <div className="py-5 min-w-max">
      <motion.div
        layoutId="menu"
        className="absolute px-10 py-10 bg-white border shadow-lg border-1 rounded-box -left-2/4"
        style={{ minWidth: 400 }}
        initial="hiddens"
        animate="visible"
      >
        {children}
      </motion.div>
    </div>
  );
};

export default SubItemContainer;

SubMenuItem.tsx

import { Hashicon } from "@emeraldpay/hashicon-react";
import React, { FunctionComponent } from "react";
import { ISubMenuItem } from "../../navbarType";

const SubMenuItem: FunctionComponent<ISubMenuItem> = (title, text) => {
  return (
    <div className="my-2 cursor-pointer group min-w-max">
      <div className="flex items-center gap-4">
        <Hashicon value={title} size={25} />
        <div className="">
          <p className="font-bold text-gray-800 group-hover:text-blue-900 text-md">
            {title}
          </p>
          <span className="text-sm font-bold text-gray-400 group-hover:text-blue-400">
            {text}
          </span>
        </div>
      </div>
    </div>
  );
};

export default SubMenuItem;

下划线.tsx

import { motion } from "framer-motion";

const Underline = () => {
  return (
    <motion.div
      className="absolute -bottom-1 left-0 right-0 h-1 bg-gradient-to-r from-blue-700 via-pink-500 to-red-500"
      layoutId="underline"
      layout
    ></motion.div>
  );
};

export default Underline;

navbarType.ts

import { CSSProperties } from "react";

export interface IMenuItem {
  text: string;
  style: CSSProperties | undefined;
}

export interface ISubMenuItem {
  title: string;
  text: string;
}

【问题讨论】:

  • 你好像不小心写了SubMenuItem来接收(title, text)而不是({ title, text })
  • 谢谢 Kausko - 我不敢相信我错过了。

标签: javascript reactjs next.js tailwind-css


【解决方案1】:

括号丢失,应该是({ title, text }),而不是SubMenuItem中的(title, text )

【讨论】:

    猜你喜欢
    • 2021-04-04
    • 2021-03-28
    • 2021-06-22
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 2017-08-04
    • 1970-01-01
    相关资源
    最近更新 更多