Render Props in Stencil

Gil Fink
2 min readApr 18, 2018

--

Stencil Logo

Before I started to use Stencil I worked a lot with React (and still working with the library). While developing React components, you are often need to use a render prop, so I wanted to see how will it work in Stencil environment. As you might figure, it works in Stencil and this gave me the idea to write a short post to explain how to use render prop in Stencil.

Render Prop

A render prop is just a name for a simple technique in which you pass to a component a function which will be used in the component render function. The reason to use a render prop is the ability for a component to share it’s inner state but without exposing it to the outside.

You can read in more details about render prop in Michael Jackson’s post:

Show Me The Code

The known example for render prop usage is a mouse capture component that holds the current mouse position. It exposes a render function prop which will handle it’s rendering. Let’s take a look at an example of that component written in Stencil:

import { Component, State, Prop } from '@stencil/core';
import Point from "../../common/Point";

@Component({
tag: 'mouse-handler',
styleUrl: 'mouse-handler.css'
})
export class MouseHandler {
@State() location: Point = { x: 0, y: 0 };
@Prop() renderFunc: (Point) => void;

constructor() {
this.handleMouseMove = this.handleMouseMove.bind(this);
}

handleMouseMove(evt) {
this.location = new Point(evt.clientX, evt.clientY);
}

render() {
return (
<div onMouseMove={this.handleMouseMove}>
{this.renderFunc(this.location)}
</div>
);
}
}

As you can see, the component expects a function called renderFunc which has the (Point) => void interface. When there is a mouse movement on the mouse-handler surface the inner location state is updated with the new current mouse position and the component is re-rendered. In the component render function we use the renderFunc to render part of the component user interface. This function will be received from the mouse-handler wrapping component.

Let’s take a look at a consuming component example:

import { Component } from '@stencil/core';

@Component({
tag: 'mouse-container',
styleUrl: 'mouse-draw.css'
})
export class MouseContainer {
render() {
return (
<div>
<mouse-handler renderFunc={({ x, y }) => (
<h1>The mouse position is ({x}, {y})</h1>
)}/>
</div>
);
}
}

In the second component, we pass the function that the mouse-handler component will use. In the example this function is just adding a heading element with the mouse position it receives.

Summary

The render prop is a React technique to help with composition of more sophisticated rendering scenarios. You can use the same technique with Stencil as well.

--

--

Gil Fink

Hardcore web developer, @sparXys CEO, Google Web Technologies GDE, Pro SPA Development co-author, husband, dad and a geek.