React Elm Wrapper

Nov 28

I’ve recently been spending a lot of time scratching my head regarding application architecture with React and Redux. It often feels like this tug of war between class based and functional programming. I’m not super attached to one paradigm or another, but I am certainly FP-curious. However, whenever I push to work exclusively in a functional way in JavaScript, I keep running into situations where the code would be cleaner or more performant if I were doing it in a mutative or class based way. It feels like I’m trying to awkwardly shoehorn functional methods into a language that really wasn’t built for it.

Enter Elm

I’ve been hearing more and more about this language Elm and how happy people are on that side of the fence, so I decided it’s finally time to give it a shot. It’ll be a good opportunity to really immerse myself in functional programming, and even if I come away feeling it’s not for me, I should hopefully come back with some new wisdom and appreciation for the React ecosystem.

In React?

The first step along that route is figuring out whether and how Elm might actually integrate with React for an easier transition. It turns out it does, and the core maintainers of Elm built out a simple harness to make it easier. However, sadly, it hasn’t been updated in a while, so it doesn’t work with React version 16. There’s not that much code to it, so I’d be hesitant to add it as a dependency, anyway. So I brought the code up to date and plugged it into my application. Worked like a charm. Here’s the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import autobind from 'class-autobind';
import PropTypes from 'prop-types';
import React from 'react';

class ReactElmWrapper extends React.Component {
  constructor(props) {
    super(props);
    autobind(this);
  }

  componentDidMount() {
    const app = this.props.src.embed(this.node, this.props.flags);

    if (this.props.ports) { this.props.ports(app.ports); }
  }

  shouldComponentUpdate() {
    return false;
  }

  storeNode(node) {
    this.node = node;
  }

  render() {
    return <div ref={this.storeNode} />;
  }
}

ReactElmWrapper.propTypes = {
  flags: PropTypes.object,
  ports: PropTypes.func,
  src: PropTypes.object.isRequired,
};

export default ReactElmWrapper;

and you can use it like:

1
2
3
function MyReactComponent() {
  return <ReactElmWrapper src={SomeImportedElmApp} />;
}

See the ground up article below for a more in-depth example.

Links

I’ve found these to be really helpful, or hope to find them helpful in the near future:


Comments

comments powered by Disqus