html - 关于如何在 React 中对这个导航栏进行 DRY 编码的任何想法?
问题描述
我正在使用 React 创建一个 SPA,并注意到在创建我的导航栏时会有很多重复。我想要的是这样的六个组件:
function Navbar() {
return (
<nav className="navbar">
<div className="navbar-items">
<Logo />
<NavbarItem1 />
<NavbarItem2 />
<NavbarItem3 />
<NavbarItem4 />
<NavbarItem5 />
</div>
</nav>
)
}
现在对于重复部分,每个组件基本上都是这样的:
function NavbarItem1() {
return (
<div className="navbar-item">
<button className="navbar-button">
<svg class="navbar-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 80" x="0px" y="0px">
<g>
<path
d="M52,7a5.006,5.006,0,0,0-5-5H7A5.006,5.006,0,0,0,2,7V56H4V7A3,3,0,1,1,8,9.816V7H6V62H48V11.9A5.009,5.009,0,0,0,52,7ZM8,60V12H46V60ZM47,10H10.974a4.9,4.9,0,0,0,0-6H47a3,3,0,0,1,0,6Z" />
<path
d="M57,8a5.006,5.006,0,0,0-5,5V52.236l5,10,5-10V13A5.006,5.006,0,0,0,57,8ZM56,48.586,54.845,47.43,54,48.7V22h2Zm-1.846,3.486,1-1.5L57,52.414l1.845-1.844,1,1.5L57,57.764ZM60,48.7l-.845-1.267L58,48.586V22h2ZM60,20H54V18h6Zm-6-4V13a3,3,0,0,1,6,0v3Z" />
<rect x="12" y="20" width="30" height="2" />
<rect x="12" y="28" width="30" height="2" />
<rect x="12" y="35" width="30" height="2" />
<rect x="12" y="43" width="30" height="2" />
<rect x="12" y="50" width="18" height="2" />
<rect x="36" y="50" width="2" height="2" />
<rect x="32" y="50" width="2" height="2" />
<rect x="40" y="50" width="2" height="2" />
</g>
</svg>
<span class="navbar-text">Item 1</span>
</button>
</div>
)
}
因此,与其创建六个基本相同的组件,是否有一种重复性较低的方式来执行此操作,或者这是人们使用 React 创建导航栏的正常方式?提前感谢您的回答。
解决方案
假设每个导航栏项之间不同的部分是图标及其文本内容,您可以将图标提取到自己的组件中,然后只需通过 props 传递图标组件和文本:
// Pass className via props so the NavbarItem can set it
function NoteIcon({ className }) {
return (
<svg
className={className}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 64 80"
x="0px"
y="0px"
>
<g>
<path d="M52,7a5.006,5.006,0,0,0-5-5H7A5.006,5.006,0,0,0,2,7V56H4V7A3,3,0,1,1,8,9.816V7H6V62H48V11.9A5.009,5.009,0,0,0,52,7ZM8,60V12H46V60ZM47,10H10.974a4.9,4.9,0,0,0,0-6H47a3,3,0,0,1,0,6Z" />
<path d="M57,8a5.006,5.006,0,0,0-5,5V52.236l5,10,5-10V13A5.006,5.006,0,0,0,57,8ZM56,48.586,54.845,47.43,54,48.7V22h2Zm-1.846,3.486,1-1.5L57,52.414l1.845-1.844,1,1.5L57,57.764ZM60,48.7l-.845-1.267L58,48.586V22h2ZM60,20H54V18h6Zm-6-4V13a3,3,0,0,1,6,0v3Z" />
<rect x="12" y="20" width="30" height="2" />
<rect x="12" y="28" width="30" height="2" />
<rect x="12" y="35" width="30" height="2" />
<rect x="12" y="43" width="30" height="2" />
<rect x="12" y="50" width="18" height="2" />
<rect x="36" y="50" width="2" height="2" />
<rect x="32" y="50" width="2" height="2" />
<rect x="40" y="50" width="2" height="2" />
</g>
</svg>
);
}
function NavbarItem({ icon: Icon, children }) {
return (
<div className="navbar-item">
<button className="navbar-button">
<Icon className="navbar-icon" />
<span className="navbar-text">{children}</span>
</button>
</div>
);
}
function Navbar() {
return (
<nav className="navbar">
<div className="navbar-items">
<Logo />
{/* Pass the correct icon component, and the text via children */}
<NavbarItem icon={NoteIcon}>Item 1</NavbarItem>
<NavbarItem icon={OtherIcon}>Item 2</NavbarItem>
<NavbarItem icon={AnotherIcon}>Item 3</NavbarItem>
</div>
</nav>
);
}
推荐阅读
- hive - Hive:插入每个部分文件的覆盖目录限制大小
- c++11 - 如果两个原子 fetch_add 同时执行会发生什么?
- xamarin.forms - Xamarin Forms - UWP 自定义渲染器:如何将子级添加到 stacklayout
- r - R:合并两个匹配的数据框列表
- php - 从字符串 PHP 中修剪文本
- android - 多个模块项目中的每个 AndroidManifest 都可以有自己的吗
部分?如何在模块之间共享资源? - google-apps-script - 使用模板表中的格式从列值创建新表
- php - CakePHP cronjob 返回 500 错误
- javascript - 仅向 React App 获取一次数据。页面重新加载后不再获取
- python - 我编写的代码在“if”语句中完美运行,但在“else”语句中不起作用