javascript - 从父文本框中搜索子组件的功能
问题描述
我有一个 SideBar 组件,它有一个名为 SideBarLink 的子组件,它指向正确的页面。
我正在尝试使用文本字段将搜索功能添加到我的侧边栏。
我已经向 SideBar 组件添加了一个文本输入,并且我试图根据搜索文本和 SideBarLink 的 text 属性之间的匹配找出隐藏 SideBarLink 组件的最佳方法。
这是我当前对侧边栏的设计,但是当我们已经知道 text 属性时(尤其是当我开始添加更多链接时),在每个 SideBarLink 上声明隐藏事件感觉很难看。
import "./SideBar.css";
import React, { useState } from "react";
import SideBarDropdown from "./SideBarDropdown";
import SideBarLink from "./SideBarLink";
import { TextInput } from "../Input";
const SideBar: React.FC = () => {
const [searchPhrase, setSearchPhrase] = useState<string>();
const acroynym = (str: string) =>
str
.split(/\s/)
.reduce((response, word) => (response += word.slice(0, 1)), "");
const match = (text: string) =>
searchPhrase
? text.toLowerCase().includes(searchPhrase?.toLowerCase()) ||
acroynym(text).toLowerCase().includes(searchPhrase?.toLowerCase())
: true;
return (
<nav id="sidebar" className="custom_scrollbar">
<ul className="list-unstyled components">
<TextInput
value={searchPhrase}
onChange={(value: string) => setSearchPhrase(value!)}
/>
<SideBarLink
to={`${urls.accounts}`}
text="Account"
icon="fas fa-plus-square"
hidden={!match("Account")}
/>
<SideBarLink
to={`${urls.customers}`}
text="Customer"
icon="fas fa-plus-square"
hidden={!match("Customer")}
/>
<SideBarLink
to={`${urls.orders}`}
text="Order"
icon="fas fa-plus-square"
hidden={!match("Order")}
/>
</ul>
</nav>
);
};
export default SideBar;
这是更新所有子组件的最佳方法吗?
解决方案
如果您想要一种快速而肮脏的方式,只需将搜索文本传递给 SideBarLink 并在那里声明您的 isMatch 函数(您还应该考虑记住您的函数,这样它就不会在每次渲染后重新声明)
但我不喜欢这种方法,因为您的 SideBarLink 是否显示与 SideBarLink 本身无关。它是侧边栏组件中呈现逻辑的一部分,因此它应该保留在那里。为了做到这一点,只需在数组中定义所有链接并映射它。像这样:
const links = useMemo(() => [
{ text: 'Account', to: `${urls.accounts}`, icon: 'fas fa-plus-square' },
{ text: 'Customer', to: `${urls.customers}`, icon: 'fas fa-plus-square' },
], []);
然后在数组上的渲染循环中:
{links.map(({ text, to, icon }) => (
<SideBarLink
text="Customer"
to={`${urls.customers}`}
icon="fas fa-plus-square"
isMatch={isMatch(text)}
/>
))}
也不要忘记记住你的 isMatch 函数:
const isMatch = useCallback(
(text: string) =>
searchPhrase
? text.toLowerCase().includes(searchPhrase?.toLowerCase()) ||
acroynym(text).toLowerCase().includes(searchPhrase?.toLowerCase())
: true,
[searchPhrase],
);