【发布时间】:2022-02-04 07:59:00
【问题描述】:
我一直在尝试使用在building a 'Strip' style menu 上找到的教程文章创建导航栏。这对我来说是一次学习经历,因为我还在学习 React、NextJs 和 TypeScript。
在对以前的问题获得一些帮助后,我现在又遇到了两个问题:
- 对象错误(主要问题)
当我将鼠标悬停在菜单项上时出现渲染问题。如果我在 MenuItem.tsx 中注释掉 {isBeingHovered && <SubItemContainer>{children}</SubItemContainer>},我可以悬停主菜单项,但子菜单项显然没有显示。当我不处理子菜单项时,非常基本的功能似乎可以工作。但是,一旦将上述行放回代码中,我就会收到以下错误
错误:对象作为 React 子对象无效(找到:带有键 {title, text} 的对象)。如果您打算渲染一组子项,请改用数组。
- 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