使用树结构 React JS 中的数据搜索 Inside Dropdown
Search Inside Dropdown with data in tree structure React JS
我开发了一个自定义组件,它呈现下拉列表,其中包含树状结构,并允许用户在下拉列表中搜索值。不知何故,搜索仅在树结构的两层之后才有效。
我们只能在 NextJS 标签的内部进行搜索。之前的关卡不渲染结果。
我的函数如下所示:
const searchFunction = (menu: treeData[], searchText: string) => {
debugger; //eslint-disable-line no-debugger
for (let i = 0; i < menu.length; i++) {
if (menu[i].name.includes(searchText)) {
setFound(true);
return menu[i].name;
} else if (!menu[i].name.includes(searchText)) {
if (menu[i].children !== undefined) {
return searchFunction(menu[i].children, searchText);
}
} else {
return 'Not Found';
}
}
};
And My data is like this:
import { treeData } from './DdrTreeDropdown.types';
export const menu: treeData[] = [
{
name: 'Web Project',
children: [
{
name: 'NextJS',
children: [
{
name: 'MongoDB',
},
{
name: 'Backend',
children: [
{
name: 'NodeJS',
},
],
},
],
},
{
name: 'ReactJS',
children: [
{
name: 'Express',
},
{
name: 'mysql',
children: [
{
name: 'jwt',
},
],
},
],
},
],
},
{
name: 'lorem project',
children: [
{
name: 'Vue Js',
children: [
{
name: 'Oracle Db',
},
{
name: 'JDBC',
children: [
{
name: 'Java',
},
],
},
],
},
{
name: 'ReactJS',
children: [
{
name: 'Express',
},
{
name: 'mysql',
children: [
{
name: 'jwt',
},
],
},
],
},
],
},
];
组件的沙箱link在这里:
https://codesandbox.io/s/upbeat-feynman-89ozi?file=/src/styles.ts
我还没有查看使用它的上下文,所以如果我遗漏了一些关于它应该如何工作的信息,我深表歉意。我假设你可以在 运行 这个函数之后调用 setFound ,这取决于它是否找到任何东西并且它只需要 return 一个值。但希望这会有所帮助。
const menu = [{"name":"Web Project","children":[{"name":"NextJS","children":[{"name":"MongoDB"},{"name":"Backend","children":[{"name":"NodeJS"}]}]},{"name":"ReactJS","children":[{"name":"Express"},{"name":"mysql","children":[{"name":"jwt"}]}]}]},{"name":"lorem project","children":[{"name":"Vue Js","children":[{"name":"Oracle Db"},{"name":"JDBC","children":[{"name":"Java"}]}]},{"name":"ReactJS","children":[{"name":"Express"},{"name":"mysql","children":[{"name":"jwt"}]}]}]}];
const searchFunction = (menu, searchText) => {
let result;
for(let i = 0; i < menu.length; i++) {
if(menu[i].name.includes(searchText)) {
return menu[i].name;
} else if(menu[i].children !== undefined) {
result = searchFunction(menu[i].children, searchText);
if(result) return result;
}
}
return null;
};
console.log(searchFunction(menu, 'NextJS'));
console.log(searchFunction(menu, 'jwt'));
console.log(searchFunction(menu, 'foo'));
查看为什么当前版本不起作用,我认为它是这样的:
- 让我们以'jwt'作为searchText。
- 我们从 'Web Project' object 开始,名称不匹配,所以我们转到 else if 块(顺便说一句,我们永远无法到达 else 块,因为 else if 条件是与 if 条件相反)。
- 'Web Project' object 确实有 children 所以我们将 return 从对 searchFunction 的新调用;请注意,'lorem project' 永远无法达到,因为我们将(无论结果如何)return searchFunction 的值并跳过循环的其余部分。
- 在我们对 searchFunction 的新调用和后续调用中,将发生相同的情况,直到我们找到匹配项或没有 children 的项。
如果我们到达一个没有 children 的项目,循环将成功地继续到该项目的兄弟姐妹。
- 如果找不到匹配项或 children 的项目,它将退出 for 循环,并且 return undefined 向上链到初始 searchFunction 的调用者。
我开发了一个自定义组件,它呈现下拉列表,其中包含树状结构,并允许用户在下拉列表中搜索值。不知何故,搜索仅在树结构的两层之后才有效。
我们只能在 NextJS 标签的内部进行搜索。之前的关卡不渲染结果。
我的函数如下所示:
const searchFunction = (menu: treeData[], searchText: string) => {
debugger; //eslint-disable-line no-debugger
for (let i = 0; i < menu.length; i++) {
if (menu[i].name.includes(searchText)) {
setFound(true);
return menu[i].name;
} else if (!menu[i].name.includes(searchText)) {
if (menu[i].children !== undefined) {
return searchFunction(menu[i].children, searchText);
}
} else {
return 'Not Found';
}
}
};
And My data is like this:
import { treeData } from './DdrTreeDropdown.types';
export const menu: treeData[] = [
{
name: 'Web Project',
children: [
{
name: 'NextJS',
children: [
{
name: 'MongoDB',
},
{
name: 'Backend',
children: [
{
name: 'NodeJS',
},
],
},
],
},
{
name: 'ReactJS',
children: [
{
name: 'Express',
},
{
name: 'mysql',
children: [
{
name: 'jwt',
},
],
},
],
},
],
},
{
name: 'lorem project',
children: [
{
name: 'Vue Js',
children: [
{
name: 'Oracle Db',
},
{
name: 'JDBC',
children: [
{
name: 'Java',
},
],
},
],
},
{
name: 'ReactJS',
children: [
{
name: 'Express',
},
{
name: 'mysql',
children: [
{
name: 'jwt',
},
],
},
],
},
],
},
];
组件的沙箱link在这里:
https://codesandbox.io/s/upbeat-feynman-89ozi?file=/src/styles.ts
我还没有查看使用它的上下文,所以如果我遗漏了一些关于它应该如何工作的信息,我深表歉意。我假设你可以在 运行 这个函数之后调用 setFound ,这取决于它是否找到任何东西并且它只需要 return 一个值。但希望这会有所帮助。
const menu = [{"name":"Web Project","children":[{"name":"NextJS","children":[{"name":"MongoDB"},{"name":"Backend","children":[{"name":"NodeJS"}]}]},{"name":"ReactJS","children":[{"name":"Express"},{"name":"mysql","children":[{"name":"jwt"}]}]}]},{"name":"lorem project","children":[{"name":"Vue Js","children":[{"name":"Oracle Db"},{"name":"JDBC","children":[{"name":"Java"}]}]},{"name":"ReactJS","children":[{"name":"Express"},{"name":"mysql","children":[{"name":"jwt"}]}]}]}];
const searchFunction = (menu, searchText) => {
let result;
for(let i = 0; i < menu.length; i++) {
if(menu[i].name.includes(searchText)) {
return menu[i].name;
} else if(menu[i].children !== undefined) {
result = searchFunction(menu[i].children, searchText);
if(result) return result;
}
}
return null;
};
console.log(searchFunction(menu, 'NextJS'));
console.log(searchFunction(menu, 'jwt'));
console.log(searchFunction(menu, 'foo'));
查看为什么当前版本不起作用,我认为它是这样的:
- 让我们以'jwt'作为searchText。
- 我们从 'Web Project' object 开始,名称不匹配,所以我们转到 else if 块(顺便说一句,我们永远无法到达 else 块,因为 else if 条件是与 if 条件相反)。
- 'Web Project' object 确实有 children 所以我们将 return 从对 searchFunction 的新调用;请注意,'lorem project' 永远无法达到,因为我们将(无论结果如何)return searchFunction 的值并跳过循环的其余部分。
- 在我们对 searchFunction 的新调用和后续调用中,将发生相同的情况,直到我们找到匹配项或没有 children 的项。 如果我们到达一个没有 children 的项目,循环将成功地继续到该项目的兄弟姐妹。
- 如果找不到匹配项或 children 的项目,它将退出 for 循环,并且 return undefined 向上链到初始 searchFunction 的调用者。