@wordpress/compose
Version:
WordPress higher-order components (HOCs).
99 lines (80 loc) • 2.19 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _element = require("@wordpress/element");
var _priorityQueue = require("@wordpress/priority-queue");
/**
* WordPress dependencies
*/
/**
* Returns the first items from list that are present on state.
*
* @param {Array} list New array.
* @param {Array} state Current state.
* @return {Array} First items present iin state.
*/
function getFirstItemsPresentInState(list, state) {
const firstItems = [];
for (let i = 0; i < list.length; i++) {
const item = list[i];
if (!state.includes(item)) {
break;
}
firstItems.push(item);
}
return firstItems;
}
/**
* Reducer keeping track of a list of appended items.
*
* @param {Array} state Current state
* @param {Object} action Action
*
* @return {Array} update state.
*/
function listReducer(state, action) {
if (action.type === 'reset') {
return action.list;
}
if (action.type === 'append') {
return [...state, action.item];
}
return state;
}
/**
* React hook returns an array which items get asynchronously appended from a source array.
* This behavior is useful if we want to render a list of items asynchronously for performance reasons.
*
* @param {Array} list Source array.
* @return {Array} Async array.
*/
function useAsyncList(list) {
const [current, dispatch] = (0, _element.useReducer)(listReducer, []);
(0, _element.useEffect)(() => {
// On reset, we keep the first items that were previously rendered.
const firstItems = getFirstItemsPresentInState(list, current);
dispatch({
type: 'reset',
list: firstItems
});
const asyncQueue = (0, _priorityQueue.createQueue)();
const append = index => () => {
if (list.length <= index) {
return;
}
dispatch({
type: 'append',
item: list[index]
});
asyncQueue.add({}, append(index + 1));
};
asyncQueue.add({}, append(firstItems.length));
return () => asyncQueue.reset();
}, [list]);
return current;
}
var _default = useAsyncList;
exports.default = _default;
//# sourceMappingURL=index.js.map