如何使用筛选结果更新博客文章列表?

问题描述 投票:0回答:1

我的博客搜索功能遇到问题。当我提交搜索表单时,过滤器/参数会更新,但为了返回请求的博客文章,我必须手动刷新页面。关于如何正确处理这个问题有什么想法吗?另外应该注意的是,我有一个交叉观察器来实现无限滚动功能。


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>}
        </>
    )
}
javascript reactjs search blogs intersection-observer
1个回答
0
投票

当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>}
        </>
    )
}

© www.soinside.com 2019 - 2024. All rights reserved.