Stable bi-directional infinite scroll React component. Load additional data from both ends of a container while maintaining current view. Used for chat, timeline, feed views.
npm install --save bx-stable-infinite-scroll
# or
yarn add bx-stable-infinite-scroll
Prop | Type | Description |
---|---|---|
loadingComponent |
ReactNode |
What to display when fetching more data (e.g. <div>Loading...</div> ). |
nextDataFn |
() => void |
Function to fetch next rows. |
nextEnd |
boolean |
No more next rows to fetch. |
nextLoading |
boolean |
Fetching next rows. |
previousDataFn |
() => void |
Function to fetch previous rows. |
previousEnd |
boolean |
No more previous rows to fetch. |
previousLoading |
boolean |
Fetching previous rows. |
initialReverse |
?boolean |
Indicate whether data will initially be loaded from top or bottom of container. Default true (loading data from top). |
children |
ReactNode |
Rows to render |
See demo code for detailed usage example.
import { concat, map } from "lodash";
import randomColor from "randomcolor";
import React, { FunctionComponent, useState } from "react";
import BxInfiniteScroll from "../../src";
const App: FunctionComponent = () => {
const [items, setItems] = useState(
map([1, 2, 3, 4, 5, 7, 8, 9, 10], (i) => {
return { color: "#AAA", text: `Initial item ${i}` };
}),
);
const [loadingNext, setLoadingNext] = useState(false);
const [loadingPrevious, setLoadingPrevious] = useState(false);
const handleNextDataLoad = () => {
setLoadingNext(true);
setTimeout(() => {
const color = randomColor();
const time = new Date().toLocaleTimeString();
const loadedItems = map([1, 2, 3, 4, 5], (i) => {
return { color, text: `Next ${i}: ${time}` };
});
setItems((prevItems) => concat(prevItems, loadedItems));
setLoadingNext(false);
}, 1000);
};
const handlePreviousDataLoad = () => {
setLoadingPrevious(true);
setTimeout(() => {
const color = randomColor();
const time = new Date().toLocaleTimeString();
const loadedItems = map([1, 2, 3, 4, 5], (i) => {
return { color, text: `Previous ${i}: ${time}` };
});
setItems((prevItems) => concat(loadedItems, prevItems));
setLoadingPrevious(false);
}, 1000);
};
return (
<>
<h4
style={{
margin: "24px 0",
}}
>
Scroll in both directions to load additional items ππ
</h4>
<div
style={{
boxShadow: "inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)",
height: "300px",
}}
>
<BxInfiniteScroll
loadingComponent={
<div style={{ padding: "8px 16px" }}>Loading 5 more items...</div>
}
nextDataFn={handleNextDataLoad}
nextEnd={false}
nextLoading={loadingNext}
previousDataFn={handlePreviousDataLoad}
previousEnd={false}
previousLoading={loadingPrevious}
>
{map(items, (item) => {
return (
<div
key={item.text}
style={{
display: "flex",
alignItems: "center",
padding: "8px 16px",
borderBottom: "1px solid #DDD",
}}
>
<div
style={{
backgroundColor: item.color,
height: "16px",
width: "16px",
borderRadius: "4px",
marginRight: "4px",
}}
/>
{item.text}
</div>
);
})}
</BxInfiniteScroll>
</div>
</>
);
};
export default App;
** π¨ Use unique keys for children**
Make sure the elements youβre passing into <BxInfiniteScroll>
have unique and consistent keys.
<BxInfiniteScroll {...props}>
{map(rows, (row) => {
return <div key={row.id}>{row.content}</div>
})}
</BxInfiniteScroll>
Author: cathykc
The Demo/Documentation: View The Demo/Documentation
Download Link: Download The Source Code
Official Website: https://github.com/cathykc/bx-stable-infinite-scroll
#react #web-development #webdev #javascript