Entry-level React Scroll component development
What is scroll component?
In short, the ability to scroll through the components of each project at a fixed height
Features: Scroll to the bottom to load more, error prompt, no more, no more data bottom prompt
Technology stack
react + react hooks + fetch
The development of
The first step is to write down the basic components
index.js
function Index(props) {
return (
<div className={'box-container'} >
<scroll>
</scroll>
</div>)}Copy the code
scroll.js
function Scroll(props) {
return (
<ul className={'scroll-container'} >
2131
</ul>)}Copy the code
item.js
function Item(props) {
return (
<div className={'item-container'} >{props. Children instanceof Array? props.children.map(item => item) : props.children }</div>
);
}
Copy the code
The second step starts rendering the list data
index.js
const [list, setList] = useState([])
const [totalCount, setTotalCount] = useState(0)
const [listQuery, setListQuery] = useState({
page: 1.rows: 10
})
// Rely on listQuery data. If the paging parameter page changes, re-send the request for new data
useEffect(() = > {
fetchData(listQuery).then(res= > {
console.log('listQuery change')
const {bookList, totalCount} = res.data
const result = [...list, ...bookList] // Merge the previous data
setList(result)
setTotalCount(totalCount)
})
}, [listQuery]);
// For a computed object similar to VUE, get the computed value when list and totalCount change
const hasMore = useMemo(() = > {
return list.length < totalCount
}, [list, totalCount])
return (
<div className={'box-container'} >
<Scroll
sourceData = {list}
renderItem = {item= > (
<Item key = {item.key}>/* This is where the contents of the Item are placed, or individual data can be passed to the Item for rendering<Item key = {item.key} item={item}></Item>* /<span>{item.title}</span>
</Item>
)}
hasMore = {hasMore}
>
</Scroll>
</div>
)
Copy the code
scroll.js
const { sourceData, renderItem, hasMore } = props
return (
<ul className={'scroll-container'} >
{
sourceData.map(renderItem)
}
</ul>
);
Copy the code
The third step is to determine whether to scroll to the bottom
const handleScroll = () = > {
// No more scrolling does not need to calculate height to load more.
if(! hasMore) {return
}
const sr = scrollRef.current // scroll for the outermost element
const sh = sr.scrollHeight
const ch = sr.clientHeight
const st = sr.scrollTop
//
if(sh - (st + 10) <= ch) {
// Load more}}Copy the code
Step 4 Load more
index.js
const [loading, setLoading] = useState(false)
useEffect(() = > {
+++ setLoading(true)
fetchPageData(listQuery).then(res= > {
console.log('listQuery change')
const {bookList, totalCount} = res.data
const result = [...list, ...bookList]
// Scroll load latency
setTimeout(() = > {
setList(result)
setTotalCount(totalCount)
+++ setLoading(false)},2000)
})
}, [listQuery]);
return (
<div className={'box-container'} >
<Scroll
sourceData={list}
renderItem={(item, index) = > (
<Item key={item.title}>
<span>{index}{index}</span>
</Item>} load={() => {// Pass the load event to the Scroll component. let num = listQuery.page + 1 let result = {... listQuery} result.page = num setListQuery(result) }} loading={loading} hasMore={hasMore} /></div>
);
Copy the code
scroll.js
const handleScroll = () => { +++ if(loading) { +++ return +++ } if(! hasMore) { return } const sr = scrollRef.current const sh = sr.scrollHeight const ch = sr.clientHeight const st = Sr. scrollTop if(sh - (st + 10) <= ch) {+++ load()}} const showLoading = useMemo(() => hasMore && loading, [hasMore, loading]); return ( <ul className={'scroll-container'} ref={scrollRef} onScroll={handleScroll}> { sourceData.map(renderItem) } // You can customize the loading icon {showLoading && <div className={'loading'}> loading... </div> } </ul> );Copy the code
The above code finishes scrolling to the bottom to load more and no more.
Error message, no more data at the bottom of the function to add loading and add judgment, need to pay attention to the priority. You can also add a reload button when loading times out…
rendering
Thank you for watching
Use the react knowledge recently learned to do a small component, I hope you can point out any shortcomings.