WordCamp US 2025: Block Composability – Interactivity API Function Inheritance

One of the more powerful features of the Interactivity API is it’s ability to inherit and replace functionality through blocks. As a simple diagram lets take a look at how this is structured:

Lets imagine a parent block with a iAPI store that looks something like this:

const { state, actions } = store('prc-quiz/controller', {
	state: {
	},
	actions: {
		onSubmit: () => {
			// Do something.
		}
	},
	callbacks: {
		beforeSubmitting: () => {
			// Do something... and then...
            actions.onSubmit();
		}
	}
});

In this example this store has an action and callback to handle the lifecycle around submissions. Now let’s imagine this block also has innerblocks. Perhaps in one use of it, you want to change how submissions work. You could write additional functions and handlers in the parent store, but that gets messy. Instead with the iAPI it couldn’t be easier, in your child block simply add a new view.js file and add something like this:

const { state, actions } = store('prc-quiz/controller', {
	actions: {
		onSubmit: () => {
			// Do something else entirely.
		}
	},
});

Now when the parent block eventually triggers its callbacks.beforeSubmitting it’s not using the onSubmit from the parent, it’s using the new onSubmit from the child. If the child is removed from the parent it’ll go back to using it’s onSubmit.

How easy is that!

Conversely child blocks or blocks with their own iAPI stores can consume, not just replace functionality from the parent block. You can imagine a parent store may have a helper function like:

const { state, actions } = store('prc-quiz/controller', {
	state: {
	},
	actions: {
		helperCalculateScore(dataIn) => {
            // Do something to dataIn so it becomes...
            return dataOut;
        }
	},
});

And you can imagine that other blocks with their own Interactivity API stores can have their own functionality that can tap into and utilize functionality from other blocks, like so:

const { state, actions } = store('prc-quiz/results', {
	state: {
	},
	actions: {
		doSomething: () => {
             const quizControllerStore = store('prc-quiz/controller');
             if ( ! quizControllerStore ) {
                 return; // Exit early if the store is unavailable.
             }
             const { actions } = quizControllerStore;
             return actions.helperCalculateScore('xyz');
        }
	},
});