admin管理员组

文章数量:1122832

I want to run a function when a block is removed. I found this action that seems appropriate

I added the following to the main block script and the code is definitely executed, because if I remove the namespace, I get an error.

wp.hooks.addAction('removeBlock', 'foo', function(arg){
  console.log('gfgdfg');
});

However when I remove a block, notthing is logged in the console. Am I doing this wrong?

I want to run a function when a block is removed. I found this action that seems appropriate https://developer.wordpress.org/block-editor/reference-guides/data/data-core-block-editor/#removeblock

I added the following to the main block script and the code is definitely executed, because if I remove the namespace, I get an error.

wp.hooks.addAction('removeBlock', 'foo', function(arg){
  console.log('gfgdfg');
});

However when I remove a block, notthing is logged in the console. Am I doing this wrong?

Share Improve this question edited Oct 15, 2022 at 10:02 Paul asked Oct 15, 2022 at 9:32 PaulPaul 1717 bronze badges 3
  • or are these redux store actions? – Paul Commented Oct 15, 2022 at 10:22
  • Yes @Paul, they are, and removeBlock() is a function for removing a block. It doesn't fire an action hook named removeBlock, but you can use wp.data.subscribe() to listen to changes in specific part of a store. – Sally CJ Commented Oct 15, 2022 at 16:24
  • I'd be interested in concrete examples of using subscribe. I found this github issue which has a suggestion github.com/WordPress/gutenberg/issues/41679 - I'm surprised there's no straightforward way like the PHP post-delete hook. – Paul Commented Oct 16, 2022 at 8:44
Add a comment  | 

2 Answers 2

Reset to default 1

I'm a little late to the party, but wanted to add my answer to help the future readers. I had the same need and after some digging I found out that this can be achieved with useEffect() hook.

Just return an anonymous function from useEffect() callback and it will be executed when the block is removed (unmounted). Passing an empty array as the 2nd parameter to useEffect() makes the callback run when the block is added or removed.

(() => {
    const {registerBlockType} = wp.blocks;
    const {createElement, useEffect} = wp.element;
    const {useBlockProps} = wp.blockEditor;

    function edit(props) {
        useEffect(() => {
            console.log('Block added');
        
            return () => {
                console.log('Block deleted');
            }
        }, []);

        return createElement('div', useBlockProps(), 'My block');
    }

    function save(props) {
        return createElement('div', useBlockProps(), 'My block');
    }

    registerBlockType('my-blocks/my-block', {
        edit: edit,
        save: save,
    });
})();

This is behaviour described in the React useEffect() documentation.

The console.log('Block deleted') gets fired when moving a block. inside the return function you have to see if the block is still a child of the parent. this works, but I bet there is a better way out there by subscribing to the block store. You need to get select from @wordpress/data

//get this block
const self = select("core/block-editor").getBlock(props.clientId);

//get this block's parents
const parents = select("core/block-editor").getBlockParents(props.clientId);

//get the immediate parent of this block
const parent = select("core/block-editor").getBlock(parents[parents.length-1]);

//if the parent has this block as a child block is there
if( parent && parent.innerBlocks && parent.innerBlocks.includes(self) ){
 console.log('block is there')
} else {
 //if the parent does not have this block as a child, the block is gone
 console.log('Block deleted');
}

本文标签: block editorRun callback on removeBlock action