Blazor Components Communication Pattern: The “Parameter-Down” and “EventCallback-up” Pattern

Andrejs Abrickis
The Startup
Published in
4 min readDec 1, 2020
Mind map by https://undraw.co/

After spending the last couple of years in Vue.js land I’ve got used to its inter-component communication paradigms. Now working on a side-project and building a Blazor app I find myself looking for the same tools I’ve practiced for a while.

One of the simplest approaches in Vue.js for parent-child component communication is the “props-down & events-up” pattern. You can read more about it in my previous article.

Without a surprise, it was easy to adapt existing knowledge and implement this pattern also in Blazor. In this article, I will show you how to extend the Pages/Counter.razor page by implementing two buttons for increasing and decreasing the count.

Executing dotnet new blazorwasm one gets the default implementation of the Pages/Counter.razor component that has a button allowing the user to increase a counter like the following code.

If we want to have another button for decreasing the count we can create a new method for that, copy the existing button’s markup and replace the onclick hander method.

Easy as that, but this approach is not scalable. What if we must add new features for the counter, e.g., multiplication or division? In this case, we would duplicate the code and increase the method count that mutates the local state of currentCount property.

The “parameter-down” & “EventCallback-up” pattern

The pattern suggests us to split the application into multiple components where each of the components has a single responsibility. The parent component is responsible for storing and updating the root state. And the child components are responsible for executing the business logic or part of it.

The state is shared by passing parameters from the parent to child component. And the update happens through a callback method that is bound to the event invoked on the child-components.

Based on the chart above we can now create two components Components/IncreaseButton.razor and Components/DecreaseButton.razor Both of them receive input from the parent-component through the Count parameter. And both have local @onclick event handlers that invoke the EventCallback with the modified counter value as a parameter.

IncreaseButton.razor and DecreaseButton.razor components

The need to explicitly define the EventCallback property on the component is an advantage for Blazor over its JavaScript counterparts. This allows avoiding magic strings of event names like this.$emit('CountChanges') as in Vue.js.

Finally, we must update the parent component by implementing the CountChangedHandler method that will receive the new count value through the method’s parameter and assign it to the currentCount property. And we must bind this handler to the child components CountChanged event’s attribute. Or in other words, pass the handler method as EventCallback through theParameter.

Conclusion

The benefit of this approach is that we have separated the logic that calculates the new counter value and delegated it to the child component. This way it loosely communicates the changed value with the parent component by invoking EventCallback. On the parent component now, there is only one method that serves as a single-entry point for updating the root state.

By applying this pattern, we can extend the parent component with more features without writing new or changing the existing handler method that updates the count. All the logic is encapsulated in the child components that allows composing an app in a loosely and extendable way.

I'm really excited about the Blazor and looking forward to seeing what applications there will be built using it. Stay tuned for more content about Vue.js and Blazor.

Cheers
/Andrejs/

--

--