Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React compatibility #90

Open
dfabulich opened this issue May 2, 2020 · 7 comments
Open

React compatibility #90

dfabulich opened this issue May 2, 2020 · 7 comments
Assignees
Labels
enhancement New feature or request

Comments

@dfabulich
Copy link

It would be cool and useful if Crank were to provide a compatibility layer to consume React components. This would provide a migration path from React to Crank, porting components from the top down.

Alternately (or as well), it could be possible to wrap Crank components as React components, allowing users to do a bottom-up migration from React to Crank.

@brainkim
Copy link
Member

brainkim commented May 2, 2020

This is not something I’m personally prioritizing at the moment because I imagine it to be very difficult. Also, I think there is a lot of unlearning people will have to do with regards to hooks, not doing side-effects in the render method, and opting into updates rather than opting out of them. As far as wrapping Crank components to use in React, I think the best way to do this is, ironically web components. The JSX typings would clash if we just tried to import Crank into a React application, and there would be no benefit of sharing elements between the two libraries, insofar as elements mean different things.

If someone is interested in this sort of stuff, please do experiment! I’m just trying to focus on other stuff right now and would only consider this once Crank’s ideas and design patterns are clearer.

@dfabulich
Copy link
Author

As far as wrapping Crank components to use in React, I think the best way to do this is, ironically web components.

I did think about that, but IMO React doesn't make it easy to consume web components, especially when passing props that aren't just strings. It's easy to set string props (as attributes on the custom element), but anything else is kind of a mess.

https://reactjs.org/docs/web-components.html "If you are using third-party Web Components, the best solution is to write a React component that behaves as a wrapper for your Web Component."

So maybe this has to wait until Crank has good web component support (see issue #47), but I think whatever work is required to create a WC generator, it wouldn't be much more work to create a React-component wrapper for the generated WCs.

As for consuming React components in Crank, I didn't mean "Crank itself should be able to directly consume React," but just that if you run crank.js and react.js in the same page, (or maybe just preact.js?) it should be possible to put a React component in a Crank app. I guess WCs could be used for that, too… but again you've got the attroperties problem

@brainkim
Copy link
Member

brainkim commented May 2, 2020

So maybe this has to wait until Crank has good web component support (see issue #47), but I think whatever work is required to create a WC generator, it wouldn't be much more work to create a React-component wrapper for the generated WCs.

Agreed

As for consuming React components in Crank, I didn't mean "Crank itself should be able to directly consume React," but just that if you run crank.js and react.js in the same page, (or maybe just preact.js?) it should be possible to put a React component in a Crank app. I guess WCs could be used for that, too… but again you've got the attroperties problem

Crank is pretty good about consuming web components and they should mostly just work because we fall back to setAttribute as a last resort. And you can also write extensions to the renderer to have different behavior for a specific tag. But unfortunately I think React is just kinda too intense to treat as a web component backend but curious to know what people have built.

@virtualfunction
Copy link

Just a couple of cents here... I'm guessing my thoughts are probably reflective of others which is why I'll jot them down as part of the wider discussion. I'm mostly looking at this from the perspective of new projects rather than porting an existing code base to Crank.

I generally agree with the idea of web components, as it gives a higher level of interoperability that goes beyond React. I think most users real motivation for compatibility isn't so much because they like/prefer React, but rather they want to leverage and reuse parts of the React ecosystem to avoid reinventing the wheel.

I feel the real pinch point here for most users will be form handling, and therefore what most people want is something has addressed best practices in regard to this. I've come from an old jQuery-esque JS world (as I'm mostly server-side) so I've had to brush up on React/Angular etc in recent months, but find myself a little disappointed in many of the solutions out there. I take issue with quite a bit of the React stuff out there because they sit on top of legacy API's (i.e. extending React.Component) or they push users into bloated solutions i.e heavyweight UX frameworks like Bootstrap that pollute markup with excessive CSS classes and CSS includes.

I see styling and lifecycle tasks like validation as separate distinct concerns, but many React form handling libraries badly conflate this. Being able to deal with the lifecycle aspects I think is important and probably easier as there seems to a consensus to use tools like Yup (or JSON schema). The styling aspect is more opinionated as I'm sure some will prefer to use tools like Bootstrap/Material whereas others like myself would rather use something that leverages SASS mixins (like Bourbon) that imo yields a smaller/cleaner more bespoke output.

Having something to address forms would certainly go a long way here, but I think it'd be nicer to see something sits nicer with Cranks paradigms than legacy React API's. While Crank and JSX seem to share JSX between them, they are different beasts otherwise from my perspective. Interestingly, JSX doesn't need to used at all (I'm still fond of CoffeeScript's syntax and found Teact plays nicely with Crank!)

Components like date/time pickers and autocomplete I feel are the commonly used UX components that many users new to crank will want to look for. I think a lot of devs are overlooking most browsers have date/time inputs so a polyfill might actually be the better way forward for these. Autocomplete libraries often tend to become complex as they try and cover all cases and actually when I was playing about a few days ago found it wasn't too hard to just write this from scratch given use cases for autocompletes can be quite nuanced. Simply documenting how to do this might actually be a helpful starting point.

So I guess my point is that some sort of form library that sits on top/alongside Crank would be very helpful.

@virtualfunction
Copy link

Just another thing to add - Preact did an "awesome Preact" repo on GH which I think was an excellent way to hold the community together in its ecosystem efforts. Maybe this would be a good thing as the ecosystem starts to builds traction (hopefully!🤞)

@virtualfunction
Copy link

@brainkim - Another note while I remember - Have you seen https://custom-elements-everywhere.com/ ???
I think I saw Ryan from Solid JS reference this elsewhere.

Anyway, they seem to have a suite of tests which is worth using as a starting point. Plus I guess if you get Crank on there, it's extra exposure (I see you've managed to get it listed here with some favourable results https://krausest.github.io/js-framework-benchmark/2020/table_chrome_84.0.4147.89.html)

@brainkim
Copy link
Member

@virtualfunction Agree with all of your suggestions. I’ll create an “awesome” repo eventually, and I’ll look into running the custom-elements-everywhere suite against Crank, though it seems like they are a little selective about which frameworks to include, and I don’t really feel like signing the Google CLA.

As for form elements, I don’t yet have a clear picture about what that would look like, and maybe it should go in its own issue. I’m not happy with any of the form element libraries for React, as they use patterns or APIs which I personally dislike like render props or hooks, and I do agree that they may be conflating various things like validation and styling. I don’t know what the ideal APIs are, so my suggestion is to just write out form elements by hand until you see a pattern emerge rather than trying to prematurely abstract things. I wrote a little bit about how Crank’s approach changes how we handle form elements (https://crank.js.org/guides/handling-events#form-elements), for instance how we don’t define defaultX-type props in favor of simply not updating form elements. I think this might change how you might design a form library for Crank somewhat.

I think my favorite html form solution to this day is Django forms (https://docs.djangoproject.com/en/3.0/topics/forms/), and any form solution should have APIs for both server and client, insofar as you want to validate on both sides.

If you have more thoughts on forms maybe open a new issue or discussion as it’s a little off-topic here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants