반응 무한 스크롤
48312 단어 reactjavascript
개요
본고에서 우리는 OpenLibrary에 http 요청을 보내고 조회와 일치하는 책 제목의 이름을 얻을 것입니다.그리고 이 결과는 페이지를 나누어 표시됩니다.사용자가 최종 문서로 스크롤할 때, 즉 화면에 나타날 때, 다음 문서를 가져옵니다.
도구
우리는 React 갈고리, 예를 들어 UseState,useffect,useRef,useCallback과 사용자 정의 갈고리를 사용할 것이다. 이 갈고리들은 http 요청을 생성하는 논리를 형성할 것이다.또한 Axios를 사용하면 이러한 논리를 단순화할 수 있습니다.
1단계 - 초기화
CodeSandbox로 이동하여 새로운 React 프로젝트를 초기화합니다. react.new
간단해.
2단계 - 요소
현재, 우리는 입력 필드를 표시할 수 있습니다. 일부div는 도서 제목을 표시하고, 두 개의 h3 표시는 불러오는 메시지와 오류 메시지를 표시합니다.
import React from "react";
import "./styles.css";
export default function App() {
return (
<div className="App">
<h1>React infinite scroll</h1>
<input type="text" />
<div>Book Title</div>
<div>Book Title</div>
<div>Book Title</div>
<div>
<h3>Loading...</h3>
</div>
<div>
<h3>There seems to be an error</h3>
</div>
</div>
);
}
그러면 다음과 같은 레이아웃이 제공됩니다.
이제 우리는 기능에 중점을 두고 뒤에 있는 댓글에 스타일을 추가할 것이다.
단계 3 - http 요청 보내기
useGetData.js
에서 src
이라는 파일을 만듭니다.우리는 또한 npm i axios
을 통해axios를 설치할 수 있다.이제 react에서 UseState와 UseEffect를 가져오고, axios에서 axios를 가져옵니다.
import { useState, useEffect } from "react";
import axios from "axios";
이것이 바로 우리가 사용자 정의 연결 작업을 하기 위해 가져와야 할 모든 내용이다.
이제 함수를 정의합니다. 이 함수는 query
매개 변수와 pageNumber
매개 변수를 받아들여 loading
과 error
상태를 나타내는 4개의 변수, 우리의 모든 책을 포함하는 books
수조와 hasMore
변수를 초기화합니다. 이 변수는 언제 결과의 끝에 도달할지 확인하고 API 호출을 중지합니다.
export default function useGetData(query, pageNumber) {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const [books, setBooks] = useState([]);
const [hasMore, setHasMore] = useState([]);
}
현재 우리는 query
매개 변수가 변경되었거나 pageNumber
이 변경되었을 때만 UseEffect를 사용하여 API 호출을 할 수 있습니다.내부적으로 loading
을 true
으로 설정하고 error
을 false
으로 설정하고자 합니다.
useEffect(() => {
setLoading(true);
setError(false);
}, [query, pageNumber]);
이 프로그램의 취지
현재, 우리는 axios를 통해 http 요청을 보낼 것입니다.우리는 요청을 취소하기 위해 cancel 변수를 설명할 것입니다. axios는 이 변수를 사용합니다.변경 사항을 조회할 때마다 요청을 보내는 것을 원하지 않기 때문에, 입력 필드에 새 문자를 입력할 때마다 요청을 보내는 것을 의미하기 때문이다.따라서 코드 효율이 떨어진다.해결 방안은 사용자가 입력을 끝낸 후에만 요청을 보내는 것이다.Axios는 이러한 이벤트가 발생했는지 쉽게 확인할 수 있습니다.
let cancel;
axios({
method: "GET",
url: "https://openlibrary.org/search.json",
params: { q: query, page: pageNumber },
cancelToken: new axios.CancelToken((c) => (cancel = c))
})
.then((res) => {
setBooks(prevBooks => {
return [...new Set([...prevBooks, ...res.data.docs.map(b => b.title)])]
})
setHasMore(res.data.docs.length > 0)
setLoading(false)
})
.catch((e) => {
if (axios.isCancel(e)) return;
setError(true)
});
return () => cancel();
보시다시피 cancelToken
키 이후의options 매개 변수 대상에 param
이라는 추가 옵션을 전달해야 합니다.이것은 CancelToken을 되돌려줍니다. axios는 이 영패를 사용하여 요청을 취소합니다.
이 중 하나는 Mini-useEffect:
useEffect(() => {
setBooks([])
}, [query])
사용자가 새 조회를 만든 후에 결과 목록을 재설정하려면 이 코드 세그먼트가 필요합니다.그렇지 않으면, 우리는 무한히 문서를 첨부할 것이며, 이전의 결과를 영원히 지우지 않을 것이다.
이 기능의 또 다른 관건은 우리의 catch
방법입니다.
catch((e) => {
if (axios.isCancel(e)) return;
setError(true)
})
if문장을 어떻게 촉발하는지 주의하십시오. 이 문장은 axios.isCancel(e)
이 true
인지 false
인지 평가합니다.이것은 키 변경이 감지되었는지 검사하여 요청을 취소하는 것과 같습니다.요청을 처리하고 오류를 받으면 setError(true)
을 사용하여 오류 상태를 업데이트합니다.
또 다른 관건은 우리의 청소 기능: return () => cancel()
이다.이 기능은 React의 UseEffect 연결로 제공되며, axios의 CancelToken 대상을 실행하는 함수를 사용할 수 있습니다.현재 요청은 끊임없이 얻은 후에만 처리됩니다.사용자가 상태 변경을 다시 입력하고 트리거하면 요청이 취소되고 미리 처리됩니다.
고기가 조금 더 있어요.
http 요청 결과를 건너뛰었습니다. 이제 처리하겠습니다. 다음은 성공적인 호출입니다.
then((res) => {
setBooks(prevBooks => {
return [...new Set([...prevBooks, ...res.data.docs.map(b => b.title)])]
})
setHasMore(res.data.docs.length > 0)
setLoading(false)
})
setState 함수 버전을 사용하면 이전 상태를 받아들이고 새 상태로 되돌아오는 함수를 설명합니다.되돌아오는 상태는 이전 서적의 비구조화 수조의 비구조화 집합과 각자의 서적 제목 필드를 추출한 후 얻은 문서의 비구조화 수조이다.알아요, 한 입.
이렇게 하는 이유는 우리가 중복된 책 이름을 가지고 있기 때문에 Set
은 모든 중복값을 쉽게 필터할 수 있고 그 대가는 수조를 바꾸는 것이다.따라서 무결성을 유지하기 위해 이 어레이의 얕은 복사본이 필요합니다.새로운 상태는 현재 이전의 책 제목과 우리의 새로운 결과이다.
일단 우리가 결과가 나오면, 우리가 이미 결과의 종점에 도달했는지 검사할 때가 되었다.이를 위해 setHasMore(res.data.docs.length > 0)
은true로 평가됩니다.우리가 어떻게 알았지?음, 검색된 데이터는 문서 그룹입니다. 만약 이 그룹의 길이가 0이라면, 우리는 우리가 이미 끝에 도달했다고 가정할 수 있습니다.
console.log(res.data)
은 우리가 검색한 데이터를 보여 줍니다.
우리의 변수로 돌아가기
사용자 정의 갈고리 끝에 있는 return {loading, error, books, hasMore}
은'전단'시각화 데이터에 필요한 모든 변수를 되돌려줍니다.
이것은 우리의 최종 useGetData.js
:
import { useState, useEffect } from "react";
import axios from "axios";
export default function useGetData(query, pageNumber) {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const [books, setBooks] = useState([]);
const [hasMore, setHasMore] = useState(false);
useEffect(() => {
setBooks([])
}, [query])
useEffect(() => {
setLoading(true)
setError(false)
let cancel;
axios({
method: "GET",
url: "https://openlibrary.org/search.json",
params: { q: query, page: pageNumber },
cancelToken: new axios.CancelToken((c) => (cancel = c))
})
.then((res) => {
setBooks(prevBooks => {
return [...new Set([...prevBooks, ...res.data.docs.map(b => b.title)])]
})
console.log(res.data)
setHasMore(res.data.docs.length > 0)
setLoading(false)
})
.catch((e) => {
if (axios.isCancel(e)) return;
setError(true)
});
return () => cancel();
}, [query, pageNumber]);
return {loading, error, books, hasMore};
}
4단계 - 결과 표시
App.js
으로 돌아가 다음 내용을 가져옵니다.
import React, { useState, useRef, useCallback } from "react";
import useGetData from "./useGetData";
import "./styles.css";
몇 가지 변수를 설명합니다.
const [query, setQuery] = useState("");
const [pageNumber, setPageNumber] = useState(1);
const { books, hasMore, loading, error } = useGetData(query, pageNumber);
우리의 query
변수는 조회 상태를 저장할 수 있도록 합니다.그리고 pageNumber
을 1로 초기화하여 첫 페이지를 표시합니다.마지막으로, 우리는 사용자 정의 갈고리에서 검색된 변수를 나타내는 비구조화된 대상을 성명했다.주의, 갈고리를 정확하게 처리하기 위해서, 우리는 반드시 query
과 pageNumber
을 전송해야 한다.
이제 다음 코드를 작성합니다.
const observer = useRef();
const lastBookElement = useCallback(
(node) => {
if (loading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && hasMore) {
setPageNumber((prevPageNumber) => prevPageNumber + 1);
}
});
if (node) observer.current.observe(node);
},
[loading, hasMore]
);
보시다시피 const observer = useRef();
을 사용하면 결과의 마지막 원소가 나타날 때 이 관찰자가 촉발된다는 것을 설명할 수 있습니다.다음 함수, 우리의 lastBookElement
, useCallBack을 사용하여 다시 만드는 것을 방지합니다. loading
상태나 hasMore
로고 변경을 변경하지 않으면, [loading, hasMore]
을 통해 의존항으로 추가합니다.
이제 useCallback 갈고리에서 HTML 노드 요소를 받습니다.우선, 만약에 loading
의 계산 결과가true라면, 우리는 반드시 돌아가야 한다. 이것은 우리가 현재 최종 노드를 검측하고 싶지 않다는 것을 의미한다.다음 평가(if (observer.current) observer.current.disconnect();
)는 관찰자를 현재 요소와 연결을 해제하여 새 문서 목록을 가져온 후 새 요소를 연결합니다.
사거리 관찰원
다음 코드 세그먼트는 인용된 노드가 창에 표시되는지, 더 많은 검색 결과가 있는지 확인하는 데 사용할 수 있습니다.
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && hasMore) {
setPageNumber((prevPageNumber) => prevPageNumber + 1);
}
});
우리는 관찰기에 new IntersectionObserver
을 분배했다. 함수를 매개 변수로 받아들이고 노드 항목 수조를 받아들이며 이 원소의 각종 속성, 예를 들어 isIntersecting
을 되돌려준다. 이것은 우리가 필요로 하는 변수이다.일단 우리가 이 노드를 가시화할 수 있다면, 우리는 페이지 번호를 1 증가시킬 것이다.
계속 합시다.
function handleSearch(e) {
setQuery(e.target.value);
setPageNumber(1);
}
우리는 현재 handleSearch
함수를 성명합니다. 이 함수는 query
과 pageNumber
을 업데이트할 것입니다.
마지막으로 HTML 구성 요소로 돌아갑니다.
return (
<div className="App">
<input type="text" value={query} onChange={handleSearch}></input>
{books.map((book, index) => {
if (books.length === index + 1) {
return (
<div ref={lastBookElement} key={book}>
{book}
</div>
);
} else {
return (
<div key={book}>
<h3>{book}</h3>
</div>
);
}
})}
{loading && (
<div>
<h3>Loading...</h3>
</div>
)}
{error && (
<div>
<h3>There seems to be an error</h3>
</div>
)}
</div>
);
먼저 입력 요소를 다음과 같이 업데이트합니다.
<input type="text" value={query} onChange={handleSearch}>
이제 값을 추적하고 onChange 메서드를 추가합니다.
다음 단계에서 우리는 우리의 결과를 그릴 것이다.
{books.map((book, index) => {
if (books.length === index + 1) {
return (
<div ref={lastBookElement} key={book}>
{book}
</div>
);
} else {
return (
<div key={book}>
{book}
</div>
);
}
})}
우리가 마지막 원소 ref
에 있을 때, 우리는 어떻게 독점 방식으로 (books.length === index + 1)
속성을 부가하는지 주의하십시오.그렇지 않으면 ref
속성이 없는 요소를 되돌려줍니다.
이제 로드와 오류 요소를 적절하게 표시할 수 있습니다.
{loading && (
<div>
<h3>Loading...</h3>
</div>
)}
{error && (
<div>
<h3>There seems to be an error</h3>
</div>
)}
이것은 우리의 최종 App.js
:
import React, { useState, useRef, useCallback } from "react";
import useGetData from "./useGetData";
import "./styles.css";
export default function App() {
const [query, setQuery] = useState("");
const [pageNumber, setPageNumber] = useState(1);
const { books, hasMore, loading, error } = useGetData(query, pageNumber);
const observer = useRef();
const lastBookElement = useCallback(
(node) => {
if (loading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && hasMore) {
setPageNumber((prevPageNumber) => prevPageNumber + 1);
}
});
if (node) observer.current.observe(node);
},
[loading, hasMore]
);
function handleSearch(e) {
setQuery(e.target.value);
setPageNumber(1);
}
return (
<div className="App">
<input type="text" value={query} onChange={handleSearch}></input>
{books.map((book, index) => {
if (books.length === index + 1) {
return (
<div ref={lastBookElement} key={book}>
{book}
</div>
);
} else {
return (
<div key={book}>
<h3>{book}</h3>
</div>
);
}
})}
{loading && (
<div>
<h3>Loading...</h3>
</div>
)}
{error && (
<div>
<h3>There seems to be an error</h3>
</div>
)}
</div>
);
}
결과
질의 가져오기:
도착 종점:
기능 데모: React Infinite Scroll - Carlos Z.
Reference
이 문제에 관하여(반응 무한 스크롤), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/ca513zn/react-infinite-scrolling-2ndh
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
우리는 React 갈고리, 예를 들어 UseState,useffect,useRef,useCallback과 사용자 정의 갈고리를 사용할 것이다. 이 갈고리들은 http 요청을 생성하는 논리를 형성할 것이다.또한 Axios를 사용하면 이러한 논리를 단순화할 수 있습니다.
1단계 - 초기화
CodeSandbox로 이동하여 새로운 React 프로젝트를 초기화합니다. react.new
간단해.
2단계 - 요소
현재, 우리는 입력 필드를 표시할 수 있습니다. 일부div는 도서 제목을 표시하고, 두 개의 h3 표시는 불러오는 메시지와 오류 메시지를 표시합니다.
import React from "react";
import "./styles.css";
export default function App() {
return (
<div className="App">
<h1>React infinite scroll</h1>
<input type="text" />
<div>Book Title</div>
<div>Book Title</div>
<div>Book Title</div>
<div>
<h3>Loading...</h3>
</div>
<div>
<h3>There seems to be an error</h3>
</div>
</div>
);
}
그러면 다음과 같은 레이아웃이 제공됩니다.이제 우리는 기능에 중점을 두고 뒤에 있는 댓글에 스타일을 추가할 것이다.
단계 3 - http 요청 보내기
useGetData.js
에서 src
이라는 파일을 만듭니다.우리는 또한 npm i axios
을 통해axios를 설치할 수 있다.이제 react에서 UseState와 UseEffect를 가져오고, axios에서 axios를 가져옵니다.import { useState, useEffect } from "react";
import axios from "axios";
이것이 바로 우리가 사용자 정의 연결 작업을 하기 위해 가져와야 할 모든 내용이다.이제 함수를 정의합니다. 이 함수는
query
매개 변수와 pageNumber
매개 변수를 받아들여 loading
과 error
상태를 나타내는 4개의 변수, 우리의 모든 책을 포함하는 books
수조와 hasMore
변수를 초기화합니다. 이 변수는 언제 결과의 끝에 도달할지 확인하고 API 호출을 중지합니다.export default function useGetData(query, pageNumber) {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const [books, setBooks] = useState([]);
const [hasMore, setHasMore] = useState([]);
}
현재 우리는 query
매개 변수가 변경되었거나 pageNumber
이 변경되었을 때만 UseEffect를 사용하여 API 호출을 할 수 있습니다.내부적으로 loading
을 true
으로 설정하고 error
을 false
으로 설정하고자 합니다.useEffect(() => {
setLoading(true);
setError(false);
}, [query, pageNumber]);
이 프로그램의 취지
현재, 우리는 axios를 통해 http 요청을 보낼 것입니다.우리는 요청을 취소하기 위해 cancel 변수를 설명할 것입니다. axios는 이 변수를 사용합니다.변경 사항을 조회할 때마다 요청을 보내는 것을 원하지 않기 때문에, 입력 필드에 새 문자를 입력할 때마다 요청을 보내는 것을 의미하기 때문이다.따라서 코드 효율이 떨어진다.해결 방안은 사용자가 입력을 끝낸 후에만 요청을 보내는 것이다.Axios는 이러한 이벤트가 발생했는지 쉽게 확인할 수 있습니다.
let cancel;
axios({
method: "GET",
url: "https://openlibrary.org/search.json",
params: { q: query, page: pageNumber },
cancelToken: new axios.CancelToken((c) => (cancel = c))
})
.then((res) => {
setBooks(prevBooks => {
return [...new Set([...prevBooks, ...res.data.docs.map(b => b.title)])]
})
setHasMore(res.data.docs.length > 0)
setLoading(false)
})
.catch((e) => {
if (axios.isCancel(e)) return;
setError(true)
});
return () => cancel();
보시다시피 cancelToken
키 이후의options 매개 변수 대상에 param
이라는 추가 옵션을 전달해야 합니다.이것은 CancelToken을 되돌려줍니다. axios는 이 영패를 사용하여 요청을 취소합니다.이 중 하나는 Mini-useEffect:
useEffect(() => {
setBooks([])
}, [query])
사용자가 새 조회를 만든 후에 결과 목록을 재설정하려면 이 코드 세그먼트가 필요합니다.그렇지 않으면, 우리는 무한히 문서를 첨부할 것이며, 이전의 결과를 영원히 지우지 않을 것이다.이 기능의 또 다른 관건은 우리의
catch
방법입니다.catch((e) => {
if (axios.isCancel(e)) return;
setError(true)
})
if문장을 어떻게 촉발하는지 주의하십시오. 이 문장은 axios.isCancel(e)
이 true
인지 false
인지 평가합니다.이것은 키 변경이 감지되었는지 검사하여 요청을 취소하는 것과 같습니다.요청을 처리하고 오류를 받으면 setError(true)
을 사용하여 오류 상태를 업데이트합니다.또 다른 관건은 우리의 청소 기능:
return () => cancel()
이다.이 기능은 React의 UseEffect 연결로 제공되며, axios의 CancelToken 대상을 실행하는 함수를 사용할 수 있습니다.현재 요청은 끊임없이 얻은 후에만 처리됩니다.사용자가 상태 변경을 다시 입력하고 트리거하면 요청이 취소되고 미리 처리됩니다.고기가 조금 더 있어요.
http 요청 결과를 건너뛰었습니다. 이제 처리하겠습니다. 다음은 성공적인 호출입니다.
then((res) => {
setBooks(prevBooks => {
return [...new Set([...prevBooks, ...res.data.docs.map(b => b.title)])]
})
setHasMore(res.data.docs.length > 0)
setLoading(false)
})
setState 함수 버전을 사용하면 이전 상태를 받아들이고 새 상태로 되돌아오는 함수를 설명합니다.되돌아오는 상태는 이전 서적의 비구조화 수조의 비구조화 집합과 각자의 서적 제목 필드를 추출한 후 얻은 문서의 비구조화 수조이다.알아요, 한 입.이렇게 하는 이유는 우리가 중복된 책 이름을 가지고 있기 때문에
Set
은 모든 중복값을 쉽게 필터할 수 있고 그 대가는 수조를 바꾸는 것이다.따라서 무결성을 유지하기 위해 이 어레이의 얕은 복사본이 필요합니다.새로운 상태는 현재 이전의 책 제목과 우리의 새로운 결과이다.일단 우리가 결과가 나오면, 우리가 이미 결과의 종점에 도달했는지 검사할 때가 되었다.이를 위해
setHasMore(res.data.docs.length > 0)
은true로 평가됩니다.우리가 어떻게 알았지?음, 검색된 데이터는 문서 그룹입니다. 만약 이 그룹의 길이가 0이라면, 우리는 우리가 이미 끝에 도달했다고 가정할 수 있습니다.console.log(res.data)
은 우리가 검색한 데이터를 보여 줍니다.우리의 변수로 돌아가기
사용자 정의 갈고리 끝에 있는
return {loading, error, books, hasMore}
은'전단'시각화 데이터에 필요한 모든 변수를 되돌려줍니다.이것은 우리의 최종
useGetData.js
:import { useState, useEffect } from "react";
import axios from "axios";
export default function useGetData(query, pageNumber) {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const [books, setBooks] = useState([]);
const [hasMore, setHasMore] = useState(false);
useEffect(() => {
setBooks([])
}, [query])
useEffect(() => {
setLoading(true)
setError(false)
let cancel;
axios({
method: "GET",
url: "https://openlibrary.org/search.json",
params: { q: query, page: pageNumber },
cancelToken: new axios.CancelToken((c) => (cancel = c))
})
.then((res) => {
setBooks(prevBooks => {
return [...new Set([...prevBooks, ...res.data.docs.map(b => b.title)])]
})
console.log(res.data)
setHasMore(res.data.docs.length > 0)
setLoading(false)
})
.catch((e) => {
if (axios.isCancel(e)) return;
setError(true)
});
return () => cancel();
}, [query, pageNumber]);
return {loading, error, books, hasMore};
}
4단계 - 결과 표시
App.js
으로 돌아가 다음 내용을 가져옵니다.import React, { useState, useRef, useCallback } from "react";
import useGetData from "./useGetData";
import "./styles.css";
몇 가지 변수를 설명합니다.const [query, setQuery] = useState("");
const [pageNumber, setPageNumber] = useState(1);
const { books, hasMore, loading, error } = useGetData(query, pageNumber);
우리의 query
변수는 조회 상태를 저장할 수 있도록 합니다.그리고 pageNumber
을 1로 초기화하여 첫 페이지를 표시합니다.마지막으로, 우리는 사용자 정의 갈고리에서 검색된 변수를 나타내는 비구조화된 대상을 성명했다.주의, 갈고리를 정확하게 처리하기 위해서, 우리는 반드시 query
과 pageNumber
을 전송해야 한다.이제 다음 코드를 작성합니다.
const observer = useRef();
const lastBookElement = useCallback(
(node) => {
if (loading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && hasMore) {
setPageNumber((prevPageNumber) => prevPageNumber + 1);
}
});
if (node) observer.current.observe(node);
},
[loading, hasMore]
);
보시다시피 const observer = useRef();
을 사용하면 결과의 마지막 원소가 나타날 때 이 관찰자가 촉발된다는 것을 설명할 수 있습니다.다음 함수, 우리의 lastBookElement
, useCallBack을 사용하여 다시 만드는 것을 방지합니다. loading
상태나 hasMore
로고 변경을 변경하지 않으면, [loading, hasMore]
을 통해 의존항으로 추가합니다.이제 useCallback 갈고리에서 HTML 노드 요소를 받습니다.우선, 만약에
loading
의 계산 결과가true라면, 우리는 반드시 돌아가야 한다. 이것은 우리가 현재 최종 노드를 검측하고 싶지 않다는 것을 의미한다.다음 평가(if (observer.current) observer.current.disconnect();
)는 관찰자를 현재 요소와 연결을 해제하여 새 문서 목록을 가져온 후 새 요소를 연결합니다.사거리 관찰원
다음 코드 세그먼트는 인용된 노드가 창에 표시되는지, 더 많은 검색 결과가 있는지 확인하는 데 사용할 수 있습니다.
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && hasMore) {
setPageNumber((prevPageNumber) => prevPageNumber + 1);
}
});
우리는 관찰기에 new IntersectionObserver
을 분배했다. 함수를 매개 변수로 받아들이고 노드 항목 수조를 받아들이며 이 원소의 각종 속성, 예를 들어 isIntersecting
을 되돌려준다. 이것은 우리가 필요로 하는 변수이다.일단 우리가 이 노드를 가시화할 수 있다면, 우리는 페이지 번호를 1 증가시킬 것이다.계속 합시다.
function handleSearch(e) {
setQuery(e.target.value);
setPageNumber(1);
}
우리는 현재 handleSearch
함수를 성명합니다. 이 함수는 query
과 pageNumber
을 업데이트할 것입니다.마지막으로 HTML 구성 요소로 돌아갑니다.
return (
<div className="App">
<input type="text" value={query} onChange={handleSearch}></input>
{books.map((book, index) => {
if (books.length === index + 1) {
return (
<div ref={lastBookElement} key={book}>
{book}
</div>
);
} else {
return (
<div key={book}>
<h3>{book}</h3>
</div>
);
}
})}
{loading && (
<div>
<h3>Loading...</h3>
</div>
)}
{error && (
<div>
<h3>There seems to be an error</h3>
</div>
)}
</div>
);
먼저 입력 요소를 다음과 같이 업데이트합니다.<input type="text" value={query} onChange={handleSearch}>
이제 값을 추적하고 onChange 메서드를 추가합니다.다음 단계에서 우리는 우리의 결과를 그릴 것이다.
{books.map((book, index) => {
if (books.length === index + 1) {
return (
<div ref={lastBookElement} key={book}>
{book}
</div>
);
} else {
return (
<div key={book}>
{book}
</div>
);
}
})}
우리가 마지막 원소 ref
에 있을 때, 우리는 어떻게 독점 방식으로 (books.length === index + 1)
속성을 부가하는지 주의하십시오.그렇지 않으면 ref
속성이 없는 요소를 되돌려줍니다.이제 로드와 오류 요소를 적절하게 표시할 수 있습니다.
{loading && (
<div>
<h3>Loading...</h3>
</div>
)}
{error && (
<div>
<h3>There seems to be an error</h3>
</div>
)}
이것은 우리의 최종 App.js
:import React, { useState, useRef, useCallback } from "react";
import useGetData from "./useGetData";
import "./styles.css";
export default function App() {
const [query, setQuery] = useState("");
const [pageNumber, setPageNumber] = useState(1);
const { books, hasMore, loading, error } = useGetData(query, pageNumber);
const observer = useRef();
const lastBookElement = useCallback(
(node) => {
if (loading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && hasMore) {
setPageNumber((prevPageNumber) => prevPageNumber + 1);
}
});
if (node) observer.current.observe(node);
},
[loading, hasMore]
);
function handleSearch(e) {
setQuery(e.target.value);
setPageNumber(1);
}
return (
<div className="App">
<input type="text" value={query} onChange={handleSearch}></input>
{books.map((book, index) => {
if (books.length === index + 1) {
return (
<div ref={lastBookElement} key={book}>
{book}
</div>
);
} else {
return (
<div key={book}>
<h3>{book}</h3>
</div>
);
}
})}
{loading && (
<div>
<h3>Loading...</h3>
</div>
)}
{error && (
<div>
<h3>There seems to be an error</h3>
</div>
)}
</div>
);
}
결과
질의 가져오기:
도착 종점:
기능 데모: React Infinite Scroll - Carlos Z.
Reference
이 문제에 관하여(반응 무한 스크롤), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ca513zn/react-infinite-scrolling-2ndh텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)