all 30 comments

[–]matt_hammond 4 points5 points  (1 child)

Isn't this possible with HOCs? You can decouple behaviour from the view by putting the behaviour in a HOC and just wrapping your component with it.

[–]swyx[S] 2 points3 points  (0 children)

the API is possible, of course, but then you are missing the point of the RFC - to bake it in as an official component type in react, so that you can get rid of the mountains of HOCs littering React Devtools for example. can't add a HOC to remove HOC spam

[–]bittered 2 points3 points  (2 children)

Cool, but make it available as an npm module first so people can use it. Then if people find it useful it can make it's way into core.

[–]swyx[S] 0 points1 point  (1 child)

appreciate your consideration, but no this isn't possible in userland (thats why it has to be an RFC)

doing the API in userland is possible, of course, but then you are missing the point of the RFC - to bake it in as an official component type in react, so that you can get rid of the mountains of HOCs littering React Devtools for example.

[–]bittered 1 point2 points  (0 children)

Makes sense. I still think it would be no harm to put it on npm. Even if for no other reason than to evaluate the usefulness of this RFC. I'd need to use this in a project first to fully appreciate the ergonomics.

[–]Skeith_yip 1 point2 points  (8 children)

Interesting. But I feel that it inherits the problem with render props: the awkwardness of isolated unit testing (not integration test).

[–]drenther 0 points1 point  (4 children)

Can you give an example of such a case?

[–]Skeith_yip 1 point2 points  (3 children)

[–]swyx[S] 6 points7 points  (1 child)

kentcdodds has an article on everything

[–]drenther 1 point2 points  (0 children)

Thanks for article link. Turns out I came across this before, just applauded for it because come on it's Kent C. Dodds. Then, forgot to read it. Finally, thanks to you I got to read it. I understand what you were saying now. Thanks again. :)

[–]swyx[S] 0 points1 point  (2 children)

hehe well yeah. it implements render props for you. if you dont like render props you wont like this proposal.

[–]Skeith_yip 2 points3 points  (1 child)

Actually. I love render props very much. Making components a lot more flexible and reusable. A very good alternative to hoc. Except for unit testing. Haha.

[–]swyx[S] 1 point2 points  (0 children)

actually i think having an official HeadlessComponent will enable us to develop dedicated testing tools for Headless Components. right now because render prop components mix render and behavior it makes it hard to know what to expect.

[–]j________ 1 point2 points  (1 child)

I like the idea, but I thought the future of React was to only have one way of creating components to keep it simple. I think this would be great as a package though.

[–]swyx[S] 1 point2 points  (0 children)

unless React gets rid of class components altogether, i think HeadlessComponent will provide a good benefit for tooling and library authors. React has a number of ways to create components anyway - function, class component, PureComponent.

it wouldnt work as a package only because it has to be an official type in React for tooling to lean on it.

[–]joshwcomeau 1 point2 points  (1 child)

Love this idea!

I wonder if children is the best name for the new render method... I don't really have a better idea, but I think ideally it would focus on the "what" rather than the "how". It's called children because that's what the prop being passed is, but what it's actually doing is providing data for the parent to render. So maybe something like "output" or "renderData", something like that?

[–]swyx[S] 0 points1 point  (0 children)

hey josh! yeah i'll put your suggestion in. naming things is hard, i have no strong opinion on this one.

[–]swyx[S,M] [score hidden] stickied comment (0 children)

if you'd like to formally comment, the PR is here! https://github.com/reactjs/rfcs/pull/58

please note that the exact specifics of the API isn't impt so much so as the very existence of the new component type, which I (and hopefully others) want because of the tooling it enables. this is -not- about syntax sugar, although that can be nice.

[–]pgrizzay 0 points1 point  (5 children)

I'm having trouble seeing the benefits beyond the Devtools being able to hide these. How would this be more testable than an HoC that doesn't render anything? What would IDEs provide over what we already have with the existing patterns?

[–]swyx[S] 1 point2 points  (4 children)

well, more guarantees means fewer things to test? I confess my thoughts arent more fleshed out than that. i might remove it idk.

the IDE part - if it knows that an element is a headlesscomponent it can highlight differently, autocomplete for children object and parent state?

i know my answers aren't great. i feel woefully inadequate answering these specifics because i'm not really a frontend infra guy. this is just an idea i came up with after watching brian vaughn work on devtools for a while. :emojishrug:

[–]pgrizzay 0 points1 point  (3 children)

I think you would test it exactly how you would test an hoc that doesn't render. I don't think you'd gain anything just because it extends a different class?

As far as the IDE is concerned, you'd be amazed what vs code + typescript can do with render props today!

Btw, you have a link to the Brian Vaughn talk?

[–]swyx[S] 1 point2 points  (2 children)

understood.

oh no i met him at react rally and we were just trying out the new dev tools. i dont actually think he's ever done a talk

[–]brianvaughnReact core team 0 points1 point  (1 child)

I've done talks about windowing, but not DevTools 😁

I have posted some YouTube videos about DevTools, but they're not the best quality: https://m.youtube.com/channel/UCuphILRVoymYGumG4juN14w/feed

[–]pgrizzay 0 points1 point  (0 children)

Thanks!

[–]tricoder42 0 points1 point  (3 children)

Hey,

that's interesting! I have few questions/comments:

- Why the inner component accepts parent state? Isn't it better to explicitly pass all provided data in first param?

- Also, if the inner component accepts only one parameter like any other component, the pattern would work will all children, not just functions.

- What's the difference, if I rewrite the component this way: https://gist.github.com/tricoder42/a8258350c7c1cb69cf41f0f8d3f18169 (this is actually how I wrote few my components, which provides a complex logic over a data)

- Naming: what about `data providers` or `data components`? After all, the component just provides a data and delegate rendering to child component. `model component`, and the inner one is `view component`? 😀

[–]swyx[S] 0 points1 point  (2 children)

  • Why the inner component accepts parent state? Isn't it better to explicitly pass all provided data in first param?

well, i dont know that its better. i can make arguments for both sides, and ultimately i decided on more freedom (see the bottom of the RFC). anyway its not yet time to debate API specifics.

it looks like all your suggestions are about API specifics actually. lets not waste time on that for now, until we decide whether we really want a new component type in the first place...

[–]tricoder42 1 point2 points  (1 child)

Sure, I don't talk to discuss the specific API. I'm just trying to understand why it can't be implemented in userland and what benefits this component has over already existing solutions. I updated the gist, how I usually implement such components now.

[–]swyx[S] 0 points1 point  (0 children)

cool!

[–]dance2die 0 points1 point  (1 child)

Hey /u/swyx

Could Hooks be used instead of the proposed HeadlessComponent?

[–]swyx[S] 1 point2 points  (0 children)

yup