作为软件开发人员,您的工作职责之一就是为使用您的网站或产品的用户提供尽可能最佳的用户体验。
构建有用且高效的搜索功能是实现此目标的方法之一。因此,如果您正在寻找在网站前端构建搜索功能的正确方法,那么您来对地方了。
前段时间,我认为必须在后端构建搜索功能并从前端调用。
但随着我继续构建应用程序,我了解到有时您可能只需要在从没有 搜索 端点的公共端点检索的数据中进行搜索。其他时候,前端搜索可能是必要的,以提高网站的速度和整体用户体验。
本教程将首先介绍我们许多人采用的“错误搜索设置方法”。然后我们将学习一种更好的方法。所以请继续关注我,让我带您踏上这段旅程。
先决条件
如果您具备以下基本知识,那么遵循本教程将很容易:
- JavaScript
- 反应
启动项目
如果您想和我一起编写代码,我编写了一个小应用程序来为您提供帮助。只需克隆 此存储库 。感兴趣的分支是 starter-code 分支。
中的说明 ReadMe 设置项目,您将看到以下屏幕:
在您现在拥有的项目中,我们正在获取文件中每个国家/地区的 COVID-19 更新,这 src/context/hatchways.js
要归功于 coronatracker .
在我们的 src/App.js
文件中,我们显示得到的结果。 结果列表上方有 搜索 src/components/Country.js
都会呈现该文件。
当用户在输入框中输入内容时, filterCountryByName
将调用该函数来搜索我们之前收集的国家/地区。此函数正在文件中构建 src/Helpers/HatchHelper.js
。
所有样式均在 src/styles/App.scss
文件中。
现在您应该能够浏览项目并找到自己的方向。让我们从如何不构建搜索功能开始。
如何不构建搜索功能
我们将重点关注 src/Helpers/HatchHelper.js
文件以构建搜索功能。
我们已经有以下代码:
// search countries by name
const filterCountryByName = (name, countries, setResults) => {
// clear search result if the search field is empty
if (name === "") {
setResults([]);
}
// discontinue if there is no search yet
if (name === null || name === "" || countries === []) return;
};
接下来,我们需要清空之前的搜索数组,这样我们就不会将新的搜索结果添加到其中。这只是为了防止我们已经进行了搜索并想进行另一次搜索。
// empty the previous search array if any
const searchResult = [];
搜索字符串 转换 为小写。这将使搜索不区分大小写。
const data = name.toLowerCase();
像这样 循环遍历各个 国家
// loop through all countries
for (const country of countries) {
}
接下来,收集每个国家名称并将其变为小写,以确保搜索不区分大小写,如下所示:
const countryName = country.countryName.toLowerCase();
下面,检查搜索字符串是否与国家名称中的一个字符( [...countryName].includes(data)
)、国家名称中的一个单词( countryName.split(" ").includes(data)
)或完整的国家名称( countryName === data
)匹配,并收集国家详细信息,如下所示:
// check if the search word or character matches
if (
[...countryName].includes(data) ||
countryName === data ||
countryName.split(" ").includes(data)
) {
searchResult.push(country);
}
循环完成后,使用以下代码行更新搜索结果:
setResults(searchResult);
该 filterCountryByName
函数现在如下所示:
// search countries by name
const filterCountryByName = (name, countries, setResults) => {
// clear search result if the search field is empty
if (name === "") {
setResults([]);
}
// discontinue if there is no search yet
if (name === null || name === "" || countries === []) return;
// empty the previous search array if any
const searchResult = [];
const data = name.toLowerCase();
// loop through all countries
for (const country of countries) {
const countryName = country.countryName.toLowerCase();
// check if the search word or character matches
if (
[...countryName].includes(data) ||
countryName === data ||
countryName.split(" ").includes(data)
) {
searchResult.push(country);
}
}
setResults(searchResult);
};
文件 中的 主要 src/App.js
替换为以下代码,以确保在搜索过程中获得正确的反馈:
{filterByNameResults && filterByNameResults.length
? filterByNameResults.map((country) => (
))
: filterByName && !filterByNameResults.length
? "No Result Found!"
: hatchLoading === "processing"
? "Fetching Data..."
: hatchLoading === "found" && hatches && hatches.length
? hatches.map((country) => )
: "No country Found! Check your Internet Connection!"}
如何测试你的搜索功能
现在让我们进行搜索并看看我们能得到什么:
以下是 错误的搜索功能 .
上述搜索方法存在什么问题?
您会注意到,搜索字符串必须满足我们指定的 3 个条件中的至少一个才能返回结果。
那么,如果用户不确定拼写,但知道国家名称中包含几个字符,该怎么办呢?
您是否注意到,用户需要花费更多时间来搜索某些单词,因为必须完整输入这些单词才能匹配?
想想这个 :ITA- 应该能够返回意大利,NIG- 应该能够返回尼日尔和尼日利亚,等等。
因此,尽管我们的搜索功能可以正常工作,但这些问题使其难以使用并对用户体验产生负面影响。现在,我们找到了实现此搜索功能的正确方法。
如何正确构建搜索功能
我们需要在当前搜索下方创建另一个搜索。
首先设置 2 个初始状态来保存 搜索字符串 和 搜索结果 ,如下所示:
const [searchString, setSearchString] = useState("");
const [searchResult, setSearchResult] = useState([]);
接下来,在第一个输入框下方创建另一个输入框,如下所示:
{/* search by name the right way*/}
setSearchString(e.target.value)}
onKeyUp={(e) =>
searchCountryByName(
e.target.value,
hatches,
setSearchResult
)
}
/>
转到 src/Helpers/HatchHelper.js
searchCountryByName 下方
创建 filterCountryByName
:
// search countries by name the right way
const searchCountryByName = (
searchString,
countries,
setSearchResult
) => {
};
将其包含在导出中,如下所示:
export { filterCountryByName, searchCountryByName };
您现在可以 src/App.js
像这样将其导入到文件中:
import { filterCountryByName, searchCountryByName } from "./Helpers/HatchHelper";
您现在应该有第二个输入框,但它还不执行任何操作:
充实功能
我们现在将构建所需的功能来工作。
首先添加以下代码行:
// clear search result if the search field is empty
if (searchString === "") {
setSearchResult([]);
}
// discontinue if there is no search yet
if (searchString === null || searchString === "" || countries === []) return;
接下来,清空前一个搜索数组(如果有),如下所示:
// empty the previous search array if any
setSearchResult([]);
然后创建一个变量,用于在搜索时保存我们的搜索结果:
let results = [];
为搜索字符串创建一个正则表达式模式,如下所示:
// create a regular expression pattern for the search string
const pattern = new RegExp(searchString, "gi");
In the code above, we are saying that we want to use this 搜索字符串 for something. While using it, we want it to be case-insensitive and we want all possible results. You can learn more about regular expressions here .
现在循环遍历各个国家并收集每个国家的名称,如下所示:
// loop through all countries
for (const country of countries) {
const countryName = country.countryName;
}
仍在循环中,测试正则表达式模式是否 countryName
。 如果为 true ,则将国家/地区详细信息添加到 结果 数组中,如下所示:
// check if the search word or character matches
if (pattern.test(countryName)) {
results.push(country);
}
使用以下代码更新搜索结果来完成:
setSearchResult(results)
该 searchCountryByName
函数现在如下所示:
// search countries by name the right way
const searchCountryByName = (
searchString,
countries,
setSearchResult
) => {
// clear search result if the search field is empty
if (searchString === "") {
setSearchResult([]);
}
// discontinue if there is no search yet
if (searchString === null || searchString === "" || countries === []) return;
// empty the previous search array if any
setSearchResult([]);
let results = [];
// create a regular expression pattern for the search string
const pattern = new RegExp(searchString, "gi");
// loop through all countries
for (const country of countries) {
const countryName = country.countryName;
// check if the search word or character matches
if (pattern.test(countryName)) {
results.push(country);
}
}
setSearchResult(results)
};
返回 src/App.js
文件并使用以下代码替换主要元素:
{filterByNameResults && filterByNameResults.length
? filterByNameResults.map((country) => (
))
: filterByName && !filterByNameResults.length
? "No Result Found!"
: searchResult && searchResult.length
? searchResult.map((country) => )
: searchString && !searchResult.length
? "No Result Found!"
: hatchLoading === "processing"
? "Fetching Data..."
: hatchLoading === "found" && hatches && hatches.length
? hatches.map((country) => )
: "No country Found! Check your Internet Connection!"}
现在,第二个搜索框的结果包含在上面。
测试你的搜索功能(正确的方法)
哇!您刚刚学习了在前端创建搜索的正确方法。
构建搜索功能的正确方法 的代码 .
如何优化你的搜索功能
我们实际上已经完成了。所以如果你很忙,你可以跳过这一步,但如果你想改进你的搜索功能,这只需要花一点时间。
您会注意到,当您以错误的方式进行搜索并且不刷新页面时,您将停留在错误方式的结果中。当使用第二个搜索框进行正确搜索时,获得最新结果会更好。
为了实现这一点,我们需要清除每次搜索的所有搜索结果 - 无论是 错误 还是 正确的 搜索。让我们执行以下操作:
在 中 src/App.js
,将 onkey 事件替换为以下内容 :
onKeyUp={(e) =>
filterCountryByName(
e.target.value,
hatches,
setFilterByNameResults,
setSearchString,
setSearchResult
)
}
第二个搜索框的 onkey 替换 :
onKeyUp={(e) =>
searchCountryByName(
e.target.value,
hatches,
setSearchResult,
setFilterByName,
setFilterByNameResults
)
}
在 src/Helpers/HatchHelper.js
的 2 个参数, filterCountryByName
如下所示:
// search countries by name
const filterCountryByName = (
name,
countries,
setResults,
setSearchString,
setSearchResult
) => {...}
接下来,在清除初始搜索结果之前,清除其他搜索字段和结果,如下所示:
// clear the other search field and results if any
setSearchString("");
setSearchResult([]);
执行相同操作 searchCountryByName
。
完成后,你应该得到以下结果:
惊人的!
这是 优化代码 .
结论
与您一起度过的这段旅程非常棒,因为我们看到了许多人所犯的错误,并知道如何通过创建可为用户提供最佳体验的搜索功能来纠正这些错误。
我相信代码还可以进一步改进。所以我鼓励你再看看代码,看看如何让它变得更好。
所有代码都在 这里 。感谢阅读!
发表评论 取消回复