How can I use ERB inside a React component? [Rails 6] - reactjs

I have a project on Rails 6.
Started migrating it to React by using react-rails. However, there are still some components which I cannot migrate to React ATM due to time limitations.
I want to be able to use the old component (partial) in my React component.
e.g let's say I have a React component:
Component.tsx
export const Component = ({post}) => {
return <div>
<ShareButton post={post}/>
</div>
}
and somehow the ShareButton should contain this:
<%= render partial: 'posts/shared/share_post_btn', locals: {event: false, post: post} %>
I read that it may be possible by using .jsx.erb but I couldn't figure out how.
Would love to get some insights!
Thank you.

I'm afraid you'll be mixing build pipelines here. The .erb is parsed by the asset pipeline, which was the default for Rails <6 and still for CSS, but this doesn't work no longer by default for yarn/webpacker-based builds that Rails 6 favoured for JS output (Rails 7 choose a new path again, I'm sorry).
Also, as components typically have actions attached, I don't really see how a mixed Rails (static HTML) based approach could work.
A few ideas:
In the end, both Rails/ERB and React create HTML. Perhaps you can simply create the same HTML that your ShareButton creates with Rails as a temporary workaround? You'd share the CSS from the new front-end project, and you can slowly migrate rebuilding components in React (when you're thinking of building component library, make sure it works with stand alone HTML/CSS).
You can load static HTML in React using dangerouslysetinnerhtml; that might be a solution if you have complex prerendered text you want to load within a React component.
Load React client side (relatively slow); wouldn't really do this for production: How to perform import/export in client-side React JSX using Babel-Standalone
Do some parsing of the HTML received in React; and render components conditionally (this approach is a bit how Rails Turbo works; a more Rails-native answer to React, Vue and the like)
Push through: none of the 'solutions' above are really satisfying if you want to end up with a clean React version.
Roll back: why use react in the first place. React is just another fancy way of rendering HTML.

Related

How to resolve React suspense on the server

In my web app I would like to render most of my content on the server and serve complete HTML. Also, I would like for each React component to fetch its own data. I don't like the Next.js' approach of "fetch the data for the whole page". React suspense seems to be a good tool for this but suspense is never resolved on the server. The best you can do with React 18 is to renderToPipeableStream but then the actual content is still being constructed on the client by injecting script tags. That's not what I want. I want plain old HTML generated on the server.
I am now using react-ssr-prepass which works fine with React 17 but it is not suited to React 18.
Is there some way to achieve this? It seems to me it would be quite common usecase.
Check react-streaming. It's the only library that helps at the moment but it's still experimental

Using React and a bundler to build drop-in script for multiple clients

Ok, so here's what I'd like to do, but I'm not sure how because I've only ever started create react app projects for single clients. But what if I had multiple clients? And what if instead of entire sites, it's just a drop in gallery that renders in the element of their choice?
-multiclientscript
-commoncomponents (react components)
-clientAlpha
-alpha.js (has logic, imports common components, renders components where client wants on their site)
-clientBeta
-beta.js (same as alpha.js, but might import different components, whatever)
Is it possible to set up a build with webpack or some other bundler to bundle all dependencies for each client into a single script file that the client can include on their page?
If so, can someone help me get pointed in the right direction, keeping in mind I've only done very vanilla CRA projects?
Thanks!
Unless you need Webpack-specific features, using Rollup might be better for this (and it's easier to configure).
But yes, it's certainly possible. Your bundle entrypoint would have e.g. (might require e.g. adding event listeners to work in all possible loading phases, but you get the gist)
import * as ReactDOM fom 'react-dom';
import Gallery from './my-components/Gallery';
Array.from(document.querySelectorAll(".my-gallery")).forEach(galleryEl => {
const id = galleryEl.dataset.galleryId;
ReactDOM.render(galleryEl, <Gallery id={id} />);
});
and the client's HTML would have
<div class="my-gallery" data-id="123" />
<script src="gallery-bundle.js"></script>
and it Should Just Work from there.
Of course you might want to consider the overhead of having to ship React and React DOM in your bundle – Preact might be an option...

Migrating From Ember to React Page by Page Exploring Options

I want to move a big Ember v1.4.0 app to React. Instead of creating a new UI from scratch. I want to start building it in React my converting pages over slowly, essentially mixing React and Ember pages in one website.
Goal:
The above is my ultimate goal, but my first goal is is to create a single page in React that is called by Ember's router.
What I have tried so far: I wanted to create a React component in a ./templates/myFirstTestPage.handlebars because, as I understand it, the router.js calls a template file. But I am unsuccessful creating a React component in the handlebars file. Firstly, I cannot use <script> to import React because <script> does not work in handlebars. Secondly, I believe the handlebars is parsing the React app in an incorrect way. Actually, I don't really understand how, and in what order, these frameworks do the rendering.
Possible solutions (but I need implementation details):
Somehow create a React component in the template folder with the .handlebars extension.
Refer to the url of a React app in the handlebars of an Ember app
Have the Ember router map the url to a jsx file. This solution seems really viable to me. I think to myself that surely the creators of Ember must have thought that people might want to have their Ember app refer to some regular html file. Hence, I hope someone might have some knowledge whether this is possible or not.
Somehow create my own router that maps urls to particular files. If its a React component, then I'd map it to my jsx file, if not, I let Ember's router take care of the mapping. I don't really know how to implement a url mapping thing though.

Difference between react habitat and react router

I just wanted to know the difference between react router and react habitat. From what I have been reading (which is not much) these two solve the same problem of externalizing components of a website. I would like to know why one would consider one above the other if they are even comparable in this manner.
React Habitat does not worry about routes or the application information architecture (IA). It simply lets some other system render HTML pages how ever it likes and will hook up one/or many React apps on the fly when ever it see's targets in the html. If a CMS content author changes the URL of a page, or adds a new page no problem React Habitat doesn't care and will continue to hook up React apps.
React Router use routes (urls) to mount React components, this means it needs to know allot about the IA of the application and cant simply be 'dumb' to it like React Habitat. If a CMS content author changes a URL React Router will no longer render, it will require a developer to update the route in the javascript. You could be fancy and dynamically load routes from the CMS but I would question is this too tightly coupled.
They both solve different problems.
1) If you are building a SPA or PWA and want to hold all the IA in the javascript application then use React Router.
2) If a system (.net/php/java/etc) is rendering your HTML such as a CMS and it holds all the IA then use React Habitat.

How to change component in react JS without using navigator?

I'm a newbie for React Native and I don't have native development experience(I only worked on several hybrid apps), while learning this react native framework, I get several questions which block my learning.
How to navigate from one page(component) to another page(component) without relying on navigatorIOS or navigator component? In Hybrid develop mode, it's so easy, just add element A with href attribute would work, but in React Native, how to do it? I read some examples, they all use navigator or navigateIOS component to do it.
Is there any interceptor mechanism in react native so that we could inject some logic before rendering or loading component, for example, we want to have interceptor to check whether user has been login?
How to save data globally (cross components)? In Hybrid mode, we have session, we have local storage, and if we angular JS framework, we could use Service or root Scope to save data, by using react native, how do we save data cross components?
Since I'm new to react native and new to native application development, these questions might be fairly stupid, if anyone could help on this.
I don't know i'm answering to your question but please check this router component for react
https://github.com/rackt/react-router
ComponentWillMount and ComponentDidMount can be used to perform some initial loading
You can use flux framework along with React which can do almost all like in angular js
https://facebook.github.io/flux/

Resources