在 React.js 中向下滚动页面时如何加载更多搜索结果?

Posted

技术标签:

【中文标题】在 React.js 中向下滚动页面时如何加载更多搜索结果?【英文标题】:How to load more search results when scrolling down the page in React.js? 【发布时间】:2020-01-06 18:57:33 【问题描述】:

我想在向下滚动页面时加载更多搜索结果。 我使用谷歌 API 书,我只想加载 10 个搜索结果,如果用户滚动到最后一个搜索元素,则自动加载下一个 10 个结果。怎么做?我需要一个代码示例,正确的解决方案应该是什么样子。感谢您的帮助。

我的 App.js 文件如下:

 import React,  useState  from "react";
 import axios from "axios";
 import './App.css';
 import 'bootstrap/dist/css/bootstrap.min.css';


const App = () => 
const [searchTerm, setSearchTerm] = useState("");
const [books, setBooks] = useState( items: [] );
const onInputChange = e => 
    setSearchTerm(e.target.value);
;

let API_URL = 'https://www.googleapis.com/books/v1/volumes';

const fetchBooks = async () => 

    if (document.getElementById("choose_search").value === "title") 

        const result = await axios.get(`$API_URL? 
q=$searchTerm&maxResults=40`);
        setBooks(result.data);
    
    else 
        const result = await axios.get(`$API_URL? 
q=inauthor:$searchTerm&maxResults=40`);
        setBooks(result.data);
    

;

const onSubmitHandler = e => 
    e.preventDefault();
    fetchBooks();
;

return (
    <section>

            <form onSubmit=onSubmitHandler id="submit">
                <label>
                    <input
                        type="search"
                        placeholder="Search books"
                        value=searchTerm
                        onChange=onInputChange
                    />
                    <button type="submit" class="btn btn- 
  success">Search</button>
                </label>
        </form>

        <div id="choose_position" class="row">
            <div class="col-2">
            <select id="choose_search" class="form-control-sm">
                <option value="" disabled selected>Select search 
 type</option>
                <option value="title">Title</option>
                <option value="author">Author</option>
                </select>
            </div>
        </div>

        <ul>
            books.items.map((book, index) => 
                return (
                <div>
                        <div class="border rounded">

                        <div class="row">
                            <div class="col-12 d-flex justify-content- 
 center p-4" >
                                <u><h5>book.volumeInfo.title</h5></u>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-4">
                                <img
                                    id="img_book"
                                    alt=`$book.volumeInfo.title book`
                                    src= 
 `http://books.google.com/books/content?id=$
                                        book.id

  &printsec=frontcover&img=1&zoom=1&source=gbs_api`
                                />
                            </div>
                            <div class="col-8">
                                typeof book.volumeInfo.description === 
 'string' && book.volumeInfo.description.length > 0 ? 
 book.volumeInfo.description : <img src="../no_description.jpg" 
 id="description_img"/>

                            </div>

                        </div>

                        <div class="row">
                            <div class="col-4"></div>
                            <div class="col-4"><b>Preview:</b> typeof 
  book.volumeInfo.previewLink === 'string' && 
  book.volumeInfo.previewLink.length > 0 ? <a href= 
 book.volumeInfo.previewLink>Link</a> : 'No data'
                            </div>
                            <div class="col-4"><b>Published date:</b> 
  typeof book.volumeInfo.publishedDate === 'string' && 
  book.volumeInfo.publishedDate.length > 0 ? book.volumeInfo.publishedDate 
  : 'No data'
                            </div>

                        </div>

                         <div class="row pb-3">  
                            <div class="col-4"></div>
                                <div class="col-4"><b>Free download:</b> 
  typeof book.accessInfo.pdf.downloadLink === 'string' && 
  book.accessInfo.pdf.downloadLink.length > 0 ? <a href= 
  book.accessInfo.pdf.downloadLink>Link</a> : 'Not avaliable'
                                </div>
                                <div class="col-4"><b>Ebook version:</b> 
  typeof book.saleInfo.isEbook === 'boolean' && book.saleInfo.isEbook === 
  true ? 'Yes' : 'No'
                            </div>
                            <br/>
                        </div>

                            </div><br/>
                    </div> 
                );
            )
        </ul>
     </section>
   );
   ;
   export default App;

【问题讨论】:

【参考方案1】:

没有插件:

componentWillMount()
  window.addEventListener('scroll', this.loadMore);


componentWillUnmount()
    window.removeEventListener('scroll', this.loadMore);


loadMore()
    if (window.innerHeight + document.documentElement.scrollTop === document.scrollingElement.scrollHeight) 
        // Do load more content here!
    

【讨论】:

谢谢。我必须稍微修改 if 条件才能在我的情况下工作 window.innerHeight + document.documentElement.scrollTop + 5 >= document.scrollingElement.scrollHeigh @HoangMinh 我也是这样做的,但我建议你使用“+1”,这样你只会加载一次数据 谢谢亚历克斯。我不知道。我将检查我的应用程序是否正在发送多个加载数据的请求。【参考方案2】:

这称为无限滚动。 如果您不想从头开始构建,可以使用外部库:

https://www.npmjs.com/package/react-infinite-scroller

https://www.npmjs.com/package/react-infinite-scroll-component

如果您想自己构建,可以按照以下教程进行操作:

https://alligator.io/react/react-infinite-scroll/

https://upmostly.com/tutorials/build-an-infinite-scroll-component-in-react-using-react-hooks

【讨论】:

以上是关于在 React.js 中向下滚动页面时如何加载更多搜索结果?的主要内容,如果未能解决你的问题,请参考以下文章

Vue页面在加载时不会向下滚动

滚动到表格底部时如何添加“加载更多”页面

在 Python 中使用 PhantomJS 向下滚动到无限页面的底部

使用 PHP 在页面向下滚动时加载 Ajax 数据

没有滚动内容时如何下拉协调器布局

仅当用户向下滚动时才加载部分页面的简单方法?