diff --git a/packages/compose/src/hooks/use-async-list/index.ts b/packages/compose/src/hooks/use-async-list/index.ts index b1856efbaa2c7f..ff53bc7b9eb99d 100644 --- a/packages/compose/src/hooks/use-async-list/index.ts +++ b/packages/compose/src/hooks/use-async-list/index.ts @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { useEffect, useState } from '@wordpress/element'; +import { flushSync, useEffect, useState } from '@wordpress/element'; import { createQueue } from '@wordpress/priority-queue'; type AsyncListConfig = { @@ -57,17 +57,16 @@ function useAsyncList< T >( setCurrent( firstItems ); const asyncQueue = createQueue(); - const append = ( nextIndex: number ) => () => { - if ( list.length <= nextIndex ) { - return; - } - setCurrent( ( state ) => [ - ...state, - ...list.slice( nextIndex, nextIndex + step ), - ] ); - asyncQueue.add( {}, append( nextIndex + step ) ); - }; - asyncQueue.add( {}, append( firstItems.length ) ); + for ( let i = firstItems.length; i < list.length; i += step ) { + asyncQueue.add( {}, () => { + flushSync( () => { + setCurrent( ( state ) => [ + ...state, + ...list.slice( i, i + step ), + ] ); + } ); + } ); + } return () => asyncQueue.reset(); }, [ list ] ); diff --git a/packages/element/CHANGELOG.md b/packages/element/CHANGELOG.md index 1f314874f65c45..562585ecf1f779 100644 --- a/packages/element/CHANGELOG.md +++ b/packages/element/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### New Features + +- Started exporting the `flushSync` function from `react-dom` + ## 5.4.0 (2023-02-15) ## 5.3.0 (2023-02-01) diff --git a/packages/element/README.md b/packages/element/README.md index aaf145b4e46efd..9fda8a6c01eaf4 100755 --- a/packages/element/README.md +++ b/packages/element/README.md @@ -213,6 +213,14 @@ _Parameters_ - _component_ `import('./react').WPComponent`: Component's instance. +### flushSync + +Forces React to flush any updates inside the provided callback synchronously. + +_Parameters_ + +- _callback_ `Function`: Callback to run synchronously. + ### forwardRef Component enhancer used to enable passing a ref to its wrapped component. diff --git a/packages/element/src/react-platform.js b/packages/element/src/react-platform.js index c819565b79553d..38ab823f357e6b 100644 --- a/packages/element/src/react-platform.js +++ b/packages/element/src/react-platform.js @@ -4,6 +4,7 @@ import { createPortal, findDOMNode, + flushSync, render, hydrate, unmountComponentAtNode, @@ -28,6 +29,13 @@ export { createPortal }; */ export { findDOMNode }; +/** + * Forces React to flush any updates inside the provided callback synchronously. + * + * @param {Function} callback Callback to run synchronously. + */ +export { flushSync }; + /** * Renders a given element into the target DOM node. *