AlexGilleran/jsx-control-statements

Feature request: Render-prop transformation.

colshacol opened this issue ยท 4 comments

Currently, jsx-control-statements has <With>, and it is great and all (I've never used it ๐Ÿ˜†), but I believe the purpose of this tool is to help developers clean up their JSX, and it is mostly used with React.

Lately in React, render-props have taken the world by storm, especially with React about to drop the new Context API in only a few days.

example usage:

1_xhcieuad1g1rpv0c8myzva

I feel as though the hideousness of render-props would be a fantastic thing for jsx-control-statements to mask.

Here's an example of what will become more of a common pattern:

jjj

And here is what could be: (Mind you, the concept is in alpha!)

skdaksdka

The deviation is not that great, no. But it is still more aesthetically pleasing, and both of these samples were run through prettier, so they represent what would be almost globally accepted. Note that prettier wouldn't allow the destructuring to live on a single line because it is quite opinionated of object-like syntax in function declarations, but less-so inside props.

๐Ÿ’ช

That's really interesting! I'm definitely be open to including it although I don't have a lot of time to work on JSX Control Statements right now myself :).

Sorry about the slow response by the way, been procrastinating while I moved house and didn't realise this had gotten to 2 weeks.

It is all good, friend. I forgot that I created this > a month ago!

I'll do some toying and see if I can get it working as a POC. ๐Ÿ‘

I don't think this will work. With args={{store0, store1, store2}} you're actually creating a new object with the known variables store0, etc. which you then pass into the component <RenderFunc>. This is quite different than the first example where you destructure the first method parameter.

To put it differently, i.e. into code without destructuring:

<Observer inject={(stores) => ({ store0, store1, store2 })}>
  <RenderFunc args={stores}>{/* fails => where does this magical variable come from??? */}
    <div>{stores.store0}</div> 
  </RenderFunc>
</Observer>

The only solution I can actually conceive of is analogous to the way the <For> statement works:

<Observer inject={(stores) => ({ store0, store1, store2 })}>
  <RenderFunc args="stores">{/* just a string */}
    <div>{stores.store0}</div>  {/* look Ma, I'm a variable now! */}
  </RenderFunc>
</Observer>

Of course, this won't work with static typing.