Nextjs如何简单实现搜索功能
AI摘要: 本文详细讲解了如何在Next.js中实现搜索功能,包括前端的防抖设计和后端的数据库查询方案。前端通过自定义hook `useDebounce` 实现输入延迟触发搜索请求,避免频繁请求;后端初期采用Prisma直接对数据库进行模糊匹配查询,并指出未来可扩展为Elasticsearch以应对高并发场景。
最近两天在做一个创业项目,目前已经有了100个注册用户,大喜~
项目的大部分代码是AI实现的,自己更多作为产品经理+bug纠错师,确保AI不会在自己的无限生成中迷失自我。好处是上线速度很快,但是缺点是很多代码自己没有真正学会,日后可能会造成麻烦,比如搜索功能。
防抖设计
前端实现实时搜索是比较容易的。通过设置状态
const [query, setQuery] = useState("") // 来保存输入框的实时状态
useEffect(()=> {
performSearch(query); // 如果query发生变化,则向后端发送搜索请求
}, [query])
但是,如果要实现防抖(延迟3s发送请求),那么useEffect的触发条件就不能是query
, 而需要想办法重新设置一个延迟对象:
const [query, setQuery] = useStat("") // 保存实时搜索关键词
function useDebounce<T>(value: T, delay?: number): T{
const [debouunceValue, setDebounceValue] = useState<T>(value) // 延迟对象
useEffect(()=>{
const timer = setTimeout(() => setDebounceValue(value), delay || 500);
return () => {
clearTimeout(timer)
}
}, [value, delay]); // 只要value变化,则debounce变化
return debounceValue;
}
const debouncedQuery = useDebounce(query, 500);
useEffect(()=>{
performSearch(debounceQuery);
}, [debouncedQuery])
通过引入新的状态debounceValue
, 其依赖query
, 但是相对query
有500ms的延迟才发生变化.
举个例子:
- 用户在0ms输入a,那么计时器预计在500ms开始搜索a
- 用户在300ms输入了b,那么此时会清除上一个计时器(clearTimeout(timer)), 并创建新的计时器,预计800ms开始搜索b
即:debounceValue
永远相对于query
延迟500ms发生变化
后端搜索
在资源量特别少的情况下,可以直接对数据库查询,使用in进行关键词搜索
export const findResourcesByKeyword = cache(
async (keyword: string, limit: number = 10) => {
const searchTerm = `%${keyword}%`;
return prisma.resources.findMany({
where: {
OR: [
{
title: {
contains: keyword,
mode: 'insensitive'
}
},
{
description: {
contains: keyword,
mode: 'insensitive'
}
},
{
subject: {
contains: keyword,
mode: 'insensitive'
}
},
{
category: {
contains: keyword,
mode: 'insensitive'
}
}
]
},
select: resourceSelect,
orderBy: [
{ created_at: 'desc' }
],
take: limit
});
});
如果后续资源量上升,并发上升,这个函数需要替换为专业的搜索中间件elasticSearch