Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
react-window-infinite-loader
Advanced tools
InfiniteLoader component inspired by react-virtualized but for use with react-window
InfiniteLoader component inspired by react-virtualized but for use with react-window
# Yarn
yarn add react-window-infinite-loader
# NPM
npm install --save react-window-infinite-loader
Name | Type | Description |
---|---|---|
children | ({ onItemsRendered: Function, ref: React$Ref }) => React$Node | Render prop. See below for example usage. |
isItemLoaded | (index: number) => boolean | Function responsible for tracking the loaded state of each item. |
itemCount | number | Number of rows in list; can be arbitrary high number if actual number is unknown. |
loadMoreItems | (startIndex: number, stopIndex: number) => Promise<void> | Callback to be invoked when more rows must be loaded. It should return a Promise that is resolved once all data has finished loading. |
minimumBatchSize | ?number | Minimum number of rows to be loaded at a time; defaults to 10. This property can be used to batch requests to reduce HTTP requests. |
threshold | ?number | Threshold at which to pre-fetch data; defaults to 15. A threshold of 15 means that data will start loading when a user scrolls within 15 rows. |
The snippet below shows a basic example of how the InfiniteLoader
can be used to wrap either a FixedSizeList
or VariableSizeList
from react-window
.
// This value is arbitrary.
// If you know the size of your remote data, you can provide a real value.
// You can also increase this value gradually (as shown in the example below).
const itemCount = 1000;
<InfiniteLoader
isItemLoaded={isItemLoaded}
itemCount={itemCount}
loadMoreItems={loadMoreItems}
>
{({ onItemsRendered, ref }) => (
<FixedSizeList
itemCount={itemCount}
onItemsRendered={onItemsRendered}
ref={ref}
{...otherListProps}
/>
)}
</InfiniteLoader>
The InfiniteLoader
component was created to help break large data sets down into chunks that could be just-in-time loaded as they were scrolled into view.
It can also be used to create infinite loading lists (e.g. Facebook or Twitter).
Here's a basic example of how you might implement that:
function ExampleWrapper({
// Are there more items to load?
// (This information comes from the most recent API request.)
hasNextPage,
// Are we currently loading a page of items?
// (This may be an in-flight flag in your Redux store for example.)
isNextPageLoading,
// Array of items loaded so far.
items,
// Callback function responsible for loading the next page of items.
loadNextPage
}) {
// If there are more items to be loaded then add an extra row to hold a loading indicator.
const itemCount = hasNextPage ? items.length + 1 : items.length;
// Only load 1 page of items at a time.
// Pass an empty callback to InfiniteLoader in case it asks us to load more than once.
const loadMoreItems = isNextPageLoading ? () => {} : loadNextPage;
// Every row is loaded except for our loading indicator row.
const isItemLoaded = index => !hasNextPage || index < items.length;
// Render an item or a loading indicator.
const Item = ({ index, style }) => {
let content;
if (!isItemLoaded(index)) {
content = "Loading...";
} else {
content = items[index].name;
}
return <div style={style}>{content}</div>;
};
return (
<InfiniteLoader
isItemLoaded={isItemLoaded}
itemCount={itemCount}
loadMoreItems={loadMoreItems}
>
{({ onItemsRendered, ref }) => (
<FixedSizeList
itemCount={itemCount}
onItemsRendered={onItemsRendered}
ref={ref}
{...props}
>
{Item}
</FixedSizeList>
)}
</InfiniteLoader>
);
}
Some use cases require cached items to be reset. For example, after a list has been sorted, previously cached items may be invalid. You can let InfiniteLoader
know that it needs to reload cached items by calling the resetloadMoreItemsCache
method.
function ExampleWrapper({
// ...
sortOrder,
}) {
// We create a reference for the InfiniteLoader
const infiniteLoaderRef = useRef(null);
const hasMountedRef = useRef(false);
// Each time the sort prop changed we called the method resetloadMoreItemsCache to clear the cache
useEffect(() => {
// We only need to reset cached items when "sortOrder" changes.
// This effect will run on mount too; there's no need to reset in that case.
if (hasMountedRef.current) {
if (infiniteLoaderRef.current) {
infiniteLoaderRef.current.resetloadMoreItemsCache();
}
}
hasMountedRef.current = true;
}, [sortOrder]);
// ...
// We passed down the ref to the InfiniteLoader component
return (
<InfiniteLoader
ref={infiniteLoaderRef}
isItemLoaded={isItemLoaded}
itemCount={itemCount}
loadMoreItems={loadMoreItems}
>
{({ onItemsRendered, ref }) => (
// ...
)}
</InfiniteLoader>
);
}
MIT © bvaughn
FAQs
InfiniteLoader component inspired by react-virtualized but for use with react-window
We found that react-window-infinite-loader demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.