Implementing Array Methods as React Components
At React Rally last year, Ryan Florence gave an amazing talk about how we’re just scratching the surface of what can be done with React components.
Over the past few months, I’ve had great fun experimenting with this idea. I’ve found that higher-order components that handle event-listening are incredibly useful. I’ve even found it remarkably straightforward (although of questionable utility) to create a set of components that mimic the SVG spec, but render to Canvas.
Today, though, I’d like to share a mildly ridiculous idea I’ve had.
EDIT: It’s a real thing now! 🎉
Filtering props
If you’ve worked with React for a while, you’ve undoubtedly ran into this situation.
You have an array of items in props, and you want to render a list of elements. Some of the items passed in, though, aren’t needed. For example, you have a list of todos, but the visibility filter is set to hide completed ones.
Here’s how one might approach the problem:
Essentially, we’re doing the filter within the component, in 1 of 2 places:
- Filter inline. Even if you’re not a separation-of-concerns curmudgeon, you have to admit that it’s a little “busy” to have all that logic in JSX
- Filter ahead of time. This, to me, is clearer, but in a less trivial component, it can move your filtering logic far from your rendering logic. It also spoils the simplicity of a component that immediately returns JSX.
I started thinking about whether there was a way to have my cake and eat it too. Could we keep the filtering logic in the JSX, without it feeling so logic-heavy?
I made a <Filter>
component that attempts to do it:
So, that’s a thing.
We pass our <Filter>
component the items
it needs to filter, and a predicate
function that will accept each item as an argument.
Instead of taking an array of children
, we take a function instead, which will build that array by applying the function to each filtered item.
Let’s see what the implementation for this <Filter>
component is:
I’m guessing that’s simpler than you were expecting!
We wrap our output in a <div>
because components can’t return arrays of elements. This is a downside to this technique, but it’s temporary.
Also: we could modify this component to accept an
element
prop that would allow you to specify a DOM element type or custom component wrapper, but I wanted to keep it simple.
Another potential side benefit: We could hide more performant methods within this abstraction.
Conclusions
Is this all a terrible idea? Quite possibly. I think it’s worth exploring though!
In these contrived examples, the benefits aren’t that clear. But, imagine having a suite of composable array methods as components:
Now this is intuitive UI code, and the idea is super intriguing to me. That said, I’m still not totally sold; performance may be an issue, and really it’s common to do a lot of this work elsewhere (eg. in memoized selectors).
What do you think? I wrote this blog post to get feedback from other React developers. Do you see any merit to this idea? Or, should it be taken behind the barn and shot? Let me know on twitter.
Thanks for reading!
I set up a basic example on JSBin for anyone who wants to tinker around with this idea :)