I don't know if there's an event or Gutenberg hook like blockMove
or blockIndexChange
, but you can use subscribe()
from the @wordpress/data package to listen to the block index changes.
Working Example using hooks
WordPress dependencies:
import { useBlockProps } from '@wordpress/block-editor';
import { useState, useEffect } from '@wordpress/element';
import { useSelect, subscribe } from '@wordpress/data';
The block's edit()
function:
function edit( { clientId } ) {
const { getBlockIndex } = useSelect( 'core/block-editor' );
// Set initial index.
const [ currentBlockIndex, setBlockIndex ] = useState( getBlockIndex( clientId ) );
// Subscribe once this block has been attached to the DOM.
useEffect( () => {
// Listen to block index changes and set the current index if necessary.
// When you're done listening, just call unsubscribe().
const unsubscribe = subscribe( () => {
const blockIndex = getBlockIndex( clientId );
if ( currentBlockIndex !== blockIndex ) {
console.log( `block move detected; from index ${ currentBlockIndex} to ${ blockIndex }` );
setBlockIndex( blockIndex ); // update current index
}
} );
console.log( `subscribed; clientId is ${ clientId }` );
// Unsubscribe; for example once this block is removed from the editor.
return function cleanup() {
unsubscribe();
console.log( `unsubscribed - stopped listening to index changes; clientId is ${ clientId }` );
};
}, [ clientId, currentBlockIndex ] ); // note the currentBlockIndex
return (
<div { ...useBlockProps() }>
Current block index: { currentBlockIndex }
</div>
);
}
So the useEffect
callback will be called when the block is explicitly moved or that its index changed because another block was moved to the above block's current position.
You can also see my answer here for an example outside an edit
function, which uses wp.domReady()
and adds a block style once the current post type is determined.