Wordpress - How to use wp.hooks.addAction() in React JS/Gutenberg?
How to use wp.hooks.addAction
?
It's basically like so, just like you've attempted:
// Hook to the hook_name action.
wp.hooks.addAction( 'hook_name', 'namespace', function(){
console.log( 'Foo Bar' );
} );
// Trigger the hook_name action.
wp.hooks.doAction( 'hook_name' );
Or for hooks which provides one or more parameters to the callback:
// Hook to the hook_name action.
wp.hooks.addAction( 'hook_name', 'namespace', function( a, b ){
console.log( a, b );
} );
// Trigger the hook_name action.
wp.hooks.doAction( 'hook_name', 'foo', [ 'bar', 'boo' ] );
I am able to successfully use
wp.hooks.applyFilters()
andwp.hooks.addFilter()
, but I'm not able to render a React Component usingwp.hooks.addAction()
.
The problem is not with your code, but it's because unlike the wp.hooks.applyFilters
function, wp.hooks.doAction
simply returns nothing or it returns undefined
:
Here an element is returned and React later rendered the element:
{ globalHooks.applyFilters( 'replace_header', <Header /> ) }
The above translates to this, which renders an element:
{ <RevisedHeader /> }
Here
undefined
is always returned, so no elements are rendered:{ globalHooks.doAction( 'after_replace_header' ) } { globalHooks.doAction( 'after_replace_header', <Header /> ) }
The above translates to this, which "does nothing good":
{ undefined }
So once again, the problem is that wp.hooks.doAction
always returns an undefined
even if for example your afterRevisedHeaderCallback
function actually returns an element or component.
Hence, use globalHooks.applyFilters
(or rather wp.hooks.applyFilters
) if you wish to render React elements/components like so:
{ globalHooks.applyFilters( 'hook_name', <FooBar /> ) }
UPDATE
then what what purpose does doAction() serve? What would be the use case?
To do other actions than what you've tried to - { globalHooks.doAction( 'after_replace_header' ) }
(here you attempted to render an element or a component). So you could instead perform AJAX requests, modify an object (e.g. an Array
), etc. You could also run ReactDOM.render
from a callback hooked via wp.hooks.addAction
, but (as you may already know) the element container has to be already attached to the DOM. But one thing for sure, wp.hooks.doAction
always returns undefined
.
Example for modifying an object
The callback (in your component):
afterRevisedHeaderCallback( arr ) {
arr.push( 'bar' );
}
It's hooked here:
globalHooks.addAction( 'after_replace_header', 'afterRevisedHeaderCallback', this.afterRevisedHeaderCallback );
Your component's render
method:
render() {
let a = [ 'foo' ];
globalHooks.doAction( 'after_replace_header', a );
return(
<div className="App">
{ globalHooks.applyFilters( 'replace_header', <Header /> ) }
{ a.join(', ') }
</div>
);
}
UPDATE 2
Just like in PHP in WordPress, do_action_ref_array
and do_action
returns nothing/NULL
, but apply_filters_ref_array
and apply_filters
both return whatever returned by the callback to a filter/hook, which yes, could be NULL
.
And if you're skeptical about the undefined
returned by wp.hooks.doAction
, then check out the source here.
UPDATE 3
Based on the example in UPDATE above, you could actually render the element/component this way...
The callback (in your component):
afterRevisedHeaderCallback( arr ) {
// arr = [ <RevisedHeader /> ]; // doesn't work
arr[0] = <RevisedHeader />; // works fine
}
Your component's render
method:
render() {
let el = [ <Header /> ];
globalHooks.doAction( 'after_replace_header', el );
return(
<div className="App">
{ globalHooks.applyFilters( 'replace_header', <Header /> ) }
{ el }
</div>
);
}
I think you could understand the trick in that approach?