-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Block Editor: Add hook: useNoRecursiveRenders (#28428)
* Block Editor: Add useNoRecursiveRenders Originally introduced in #28405 to prevent Reusable Blocks from infinitely and fatally recurring, React hook `useNoRecursiveRenders` has a place in the block-editor package so that other block types susceptible to recursion can be fixed too. * Update variables to reflect uses beyond Reusable Block * useNoRecursiveRenders: Use Set instead of Array * Add JSDoc comment.
- Loading branch information
Showing
5 changed files
with
52 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
packages/block-editor/src/components/use-no-recursive-renders/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { | ||
createContext, | ||
useCallback, | ||
useContext, | ||
useMemo, | ||
} from '@wordpress/element'; | ||
|
||
const RenderedRefsContext = createContext( new Set() ); | ||
|
||
// Immutably add to a Set | ||
function add( set, element ) { | ||
const result = new Set( set ); | ||
result.add( element ); | ||
return result; | ||
} | ||
|
||
/** | ||
* A React hook for keeping track of blocks previously rendered up in the block | ||
* tree. Blocks susceptible to recursiion can use this hook in their `Edit` | ||
* function to prevent said recursion. | ||
* | ||
* @param {*} uniqueId Any value that acts as a unique identifier for a block instance. | ||
* | ||
* @return {[boolean, Function]} A tuple of: | ||
* - a boolean describing whether the provided id | ||
* has already been rendered; | ||
* - a React context provider to be used to wrap | ||
* other elements. | ||
*/ | ||
export default function useNoRecursiveRenders( uniqueId ) { | ||
const previouslyRenderedBlocks = useContext( RenderedRefsContext ); | ||
const hasAlreadyRendered = previouslyRenderedBlocks.has( uniqueId ); | ||
const newRenderedBlocks = useMemo( | ||
() => add( previouslyRenderedBlocks, uniqueId ), | ||
[ uniqueId, previouslyRenderedBlocks ] | ||
); | ||
const Provider = useCallback( | ||
( { children } ) => ( | ||
<RenderedRefsContext.Provider value={ newRenderedBlocks }> | ||
{ children } | ||
</RenderedRefsContext.Provider> | ||
), | ||
[ newRenderedBlocks ] | ||
); | ||
return [ hasAlreadyRendered, Provider ]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 0 additions & 29 deletions
29
packages/block-library/src/block/use-no-recursive-renders.js
This file was deleted.
Oops, something went wrong.