Sitemap
Netanel Basal

Learn development with great articles

Follow publication

Going Renderless in Angular: All of the Functionality, None of the Render

--

You probably don’t know this, but as part of my daily routine, I work with both Angular and React. I’m also a big fan of Vue and Svelte, and follow the progress there. In this article, I want to show how to achieve with Angular what are known as renderless components in Vue, and render props in React.

As the name suggests, renderless components refers to components that don’t render anything; their sole responsibility is to provide reusable functionality. Let’s take the toggle example from this article written in Vue, and convert it to Angular. Here’s the Vue version:

The toggle renderless component is responsible for providing an API for toggling a view. It doesn’t care how the view is structured or styled. We can achieve the same functionality in Angular by using structural directives:

Using Structural Directives

A structural directive changes the DOM layout by adding and removing DOM elements (i.e., a view). In addition to that, it also has a powerful feature of providing a context object that is be available to anyone that consumes it.

Let’s create a toggle structural directive that exposes the API through the context property:

We’re creating the view and passing the public API we want to expose through the context, which is the second parameter for createEmbeddedView. The neat thing here is that TemplateRef takes a generic which serves as the context type. Modern IDEs like Webstorm will infer it automatically in the template. Let’s use it:

Thanks Webstorm! 😀

Using ExportAs

For the second case, let’s use the React official example of render props. Render props provide us with a way to share the state or behavior that one component encapsulates, with other components that need that same state. For example, the following React component tracks the mouse position in a web app:

We use the children render prop as a a function that exposes the component’s state to any consumer.

This technique makes the behavior that we need to share extremely portable. To use that behavior, render a <Mouse> with a render prop, that tells it what to render with the current (x, y) of the cursor:

Let’s create the same functionality with Angular:

The MouseComponent isn’t concerned with its content. It exposes its API by using the exportAs property, which tells Angular that we can use this component API in the template:

And that’s all there is to it. We can also use the exportAs technique to create the toggle component we wrote earlier instead of using a structural directive.

Summary

I don’t think there is a right or wrong when it comes to using a structural directive or the exportAs feature. The benefits of using structural directives are that we can define an explicit API that we want to expose in the view, and easily control whether to render the view or not. When we still need some portion of view, like in the MouseComponent example, we can use a component and the exportAs feature.

🚀 In Case You Missed It

Here are a few of my open source projects:

  • Akita: State Management Tailored-Made for JS Applications
  • Spectator: A Powerful Tool to Simplify Your Angular Tests
  • Transloco: The Internationalization library Angular
  • Forms Manager: The Foundation for Proper Form Management in Angular
  • Cashew: A flexible and straightforward library that caches HTTP requests
  • Error Tailor — Seamless form errors for Angular applications

And many more!

Follow me on Medium or Twitter to read more about Angular, Akita and JS!

--

--

Netanel Basal
Netanel Basal
Netanel Basal
Netanel Basal

Written by Netanel Basal

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.

Responses (5)