我的博客搜索功能遇到问题。当我提交搜索表单时,过滤器/参数会更新,但为了返回请求的博客文章,我必须手动刷新页面。关于如何正确处理这个问题有什么想法吗?另外应该注意的是,我有一个交叉观察器来实现无限滚动功能。
export default function Posts (){
const {title} = useParams()
const [searchParams,setSearchParams] = useSearchParams()
const [posts,setPosts] = useState([])
const [morePosts ,setMorePosts] =useState(true)
const [page,setPage ]= useState(0)
const elementRef = useRef(null)
const filter = searchParams.get('filter')
const [searchField,setSearchField] = useState('')
const onSearchChange=(e)=>{
setSearchField(e.target.value)
}
//handle search
const submissionHandler =(e)=>{
e.preventDefault()
e.target.reset()
setSearchParams({filter:searchField})
setSearchField('')
}
const onIntersect=(entries)=>{
if(entries[0].isIntersecting && morePosts ){
fetchPosts(`http://localhost:4000/blog?skip=${page}&limit=1&q=${filter?filter:''}`)
}
}
function fetchPosts(url){
fetch(url,{
method:'get',
mode:'cors',
})
.then(response=>response.json())
.then(data=>{
if (data.posts.length === 0){
setMorePosts(false)
}
else if(data.success){
setPosts(p=>[...p,...data.posts])
setPage(prev=>prev+1)
}
})
}
useEffect(()=>{
const observer = new IntersectionObserver(onIntersect)
if (observer && elementRef.current){
observer.observe(elementRef.current)
}
return ()=>{
if(observer){
observer.disconnect()
}
}
},[posts,filter])
return(
<>
<FormComponent
style={{width:'20rem',alignSelf:'center',marginBottom:'10pt'}}
onSubmit={submissionHandler}
>
<input type='text' placeholder='Search Posts' value={searchField} onChange={e=>onSearchChange(e)}/>
</FormComponent>
{posts.map((post,i)=>{
const publishedDate = new Date(post.published_at)
const options = { year: 'numeric', month: 'short', day: 'numeric' }
const postDate = publishedDate.toLocaleDateString('en-us',options)
return (
<BlogCard
key={i+post.title}
id={i}
cardImage={post.post_img}
slug={post.slug}
title={post.title}
author={post.author}
body={post.body}
date={postDate}
tags={
post.tags.map((tag,i)=>{
return <span
style={{cursor:'pointer'}} key={i} >
{tag}
</span>
})
}
categories={
post.categories.map((cat,i)=>{
return <span
style={{cursor:'pointer'}} key={i} >
{cat}
</span>
})
}
/>
)
})}
{morePosts && <div ref={elementRef}>...Load More Posts</div>}
</>
)
}
当submissionHandler运行时,它无法清空“posts”数组,同时将“morePosts”值设置为true,将“page”值设置为0。导航回博客路径时还需要重置。
export default function Posts (){
const {title} = useParams()
const [searchParams,setSearchParams] = useSearchParams()
const [posts,setPosts] = useState([])
const [morePosts ,setMorePosts] =useState(true)
const [page,setPage ]= useState(0)
const elementRef = useRef(null)
const filter = searchParams.get('filter')
const [searchField,setSearchField] = useState('')
const location = useLocation()
// create helper function to delete all posts
const resetPostlist =()=>{
setPosts([])
setMorePosts(true)
setPage(0)
}
const onSearchChange=(e)=>{
setSearchField(e.target.value)
}
const submissionHandler =(e)=>{
e.preventDefault()
e.target.reset()
resetPostlist() //placed the reset function here
setSearchParams({filter:searchField})
setSearchField('')
}
//resets to default posts when user navigates to blog
useEffect(()=>{
if (location.pathname === '/blog'){
resetPostlist()
}
},[location])
const onIntersect=(entries)=>{
if(entries[0].isIntersecting && morePosts ){
fetchPosts(`http://localhost:4000/blog?skip=${page}&limit=1&q=${filter?filter:''}`)
}
}
function fetchPosts(url){
fetch(url,{
method:'get',
mode:'cors',
})
.then(response=>response.json())
.then(data=>{
if (data.posts.length === 0){
setMorePosts(false)
}else if (data.success){
setPosts(p=>[...p,...data.posts])
setPage(prev=>prev+1)
}
})
}
useEffect(()=>{
const observer = new IntersectionObserver(onIntersect)
if (observer && elementRef.current){
observer.observe(elementRef.current)
}
return ()=>{
if(observer){
observer.disconnect()
}
}
},[posts,filter])
return(
<>
<FormComponent
style={{width:'20rem',alignSelf:'center',marginBottom:'10pt'}}
onSubmit={submissionHandler}
>
<input type='text' placeholder='Search Posts' value={searchField} onChange={e=>onSearchChange(e)}/>
</FormComponent>
{posts.map((post,i)=>{
const publishedDate = new Date(post.published_at)
const options = { year: 'numeric', month: 'short', day: 'numeric' }
const postDate = publishedDate.toLocaleDateString('en-us',options)
return (
<BlogCard
key={i+post.title}
id={i}
cardImage={post.post_img}
slug={post.slug}
title={post.title}
author={post.author}
body={post.body}
date={postDate}
tags={
post.tags.map((tag,i)=>{
return <span
style={{cursor:'pointer'}} key={i} >
{tag}
</span>
})
}
categories={
post.categories.map((cat,i)=>{
return <span
style={{cursor:'pointer'}} key={i} >
{cat}
</span>
})
}
/>
)
})}
{morePosts && <div ref={elementRef}>...Load More Posts</div>}
</>
)
}