"pure" HTML to navigate inside React SPA - html

I know that internal links in a React single page application need to use the React router navigate function instead of normal hyperlinks, or they'll cause the entire application to reload from scratch. And the idiomatic solution to this is the <Link> component.
However, I have to pass internal links as strings to a third-party library function. It allows HTML tags in the string data, like <a>. But I can't pass React JSX snippets directly.
(The specific use case is adding hyperlinks inside a Google Charts type=Table visualization. The react-google-charts wrapper has an example but it only works for outbound links, not to navigate inside the app.)
My research has revealed that one of the following general ideas might work, but given the finickiness of React when it comes to non-idiomatic solutions, I want an expert option:
Use a React <Link> component and render it to an HTML string before handoff to the non-React code.
Generate <a href="Internal/SPA/page" onclick="spaLink"> links and export a function spaLink(eventdata), doing some hack with global/window data to find the router navigate function.
Generate <a href="Internal/SPA/page" class="spaLink"> links and inside a React component, programmatically wire up a click handler that selectively intercepts events coming from that class.
Other approaches that solve the problem of invoking SPA navigation from HTML are welcome. Frame challenges that I should switch to a different visualization library that allows arbitrary JSX snippets in arbitrary places, are not. This tail does not wag the dog of chart library selection.

Related

Should every part of a web app be a react component?

I haven't touched React in over 2 years, and a bit confused looking back at my old code. For example, if I were to build an instagram clone, would I utilize html templates and inject javascript as such as
<div id="reactEntry">
Loading ...
</div>
for the login page, profile page, etc.
and use react components for main logic? for example, dynamically rendering posts and comments?
Or would it be smarter to make everything a react component-- login page, profile page, etc.
would it be smarter to make everything a react component-- login page, profile page, etc. - yes. As you don't need to rely much on other libraries and can use routing between pages. Also, there is performance benefit for a fully react app.
Having other components along with react component would not cause any harm as long as you don't dom manipulate the react component.
Or would it be smarter to make everything a react component-- login
page, profile page, etc.
There are benefits of using react components over the traditional multi-page web apps.
Since most react apps are Single Page Applications(SPA), hence they are fetched once, and then virtual dom handles the rendering of various components. This is faster than the tree-based document rendering.
Components are re-usable. Say you need a Document upload form - consisting of a drag and drop file field and an upload button. You could simply create a component, and keep using it at multiple places. All components have their internal logic, which makes it easier to manipulate and define them. Such an approach ensures a consistent app look and facilitates codebase maintenance and growth.
Plugins like react-router can handle page transitions, by using its navigational components. You could do partial renders too, giving you a faster UI/UX experience than rendering the entire pages.

Best way to render React Components inside HTML templates?

I would like to to use React with Django non Single Page App way - Django will take care of routing, and rendering HTML templates and serving data.
React should be used just on some specific components inside HTML page for eg. (dropdowns, autocomplete, modals), ideally being able to just drop for eg. div element with a class inside HTML and pass props for React component.
What’s the best - maintainable, scalable solution to go about this ?
See django-jsx package and also server side rendering paper. I'm not a frontend specialist but when I've faced such problem, my friends offered me to google isomorphic app with django and react.
I found this add React to an HTML page in one minute page/example to be absolutely painless in rendering a React component inside of a Django template!
This probably isn't what you want to do, given that React has a pretty robust ecosystem around it for building performant single page applications (SPA's). You should be able to decouple your React site from your Django app. Then you'd be able to throw up your React app on a performant CDN, rather than having your Django server hosting every visitor.
But if you insist, the most straightforward way to proceed would probably be to create an index.js & index.html at each Django route. In other words, make a separate "React app" at each route, which Django will serve as users go to each endpoint. I've seen this done before. It's laggy and inefficient (relative to an SPA), but can be done.
If you really intend to go so far as to write raw HTML/CSS/JS and just use React for bits and pieces in between, you'll probably be looking to invoke ReactDOM.render using a variety of second arguments (called container) rather than the standard React-y way of doing a single ReactDOM.render(<App />, document.getElementById('root')); for the whole app to inject into a barebones HTML template.
I notice you tagged your question with server side rendering. If that is a hard requirement for you for some reason, I'd look into using next.js, a Node framework optimized for exactly that.

Polymer elements work with non polymer website?

Simple question but can I build a single page form using polymer that can be launched, through a CTA button, from a non polymer website?
I need this form to store the values in json format, and then populate a data table within my polymer web app by parsing that json data.
So once I've got my polymer form page built, I'm going to wrap it inside of this CTA button that launches the page when clicked. This CTA needs to be distributed on multiple clients sites, so "third party" sites that I have no control over.
how could I bake in polymers required imports, so that it can run on their website?
You can have all the necessary imports inlcuding Polymer inside your form element. But there are two files that you'll have to import in your CTA button
Your form element
Polyfill webcomponent-lite
There are two ways in which you can achieve having all Polymer files accessible to you in your element
You can use cdn to call to files like polymer.html
Better method will be to vulcanize all the required files including your element into one file (or two one for html and one for js if you use crisper also) so that there is no load on client side to fetch resources.
Webcomponent-lite.min.js you'll have to keep outside of your vulcanized file.
So, so far you'll have to export a package of 3-4(CTA button, webcomponents-lite, your vulcanized element) files minimum to your client.
This should do the trick.

ClojureScript google closure code splitting partial loading

I'm coming from a javascript/react/react-router/webpack background to a clojurescript/om environment.
With webpack & react-router it was possible to split my code and only load the javascript needed. E.g. on /login I would only load the js necessary to display the login-page everything else would be left out.
How do I the same with clojurescript/om?
Apparently it's possible to split your code into multiple files: https://github.com/clojure/clojurescript/wiki/Compiler-Options#modules
The question is how do I only load the code necessary to render the current page: /login for example...
With webpack I would manually write require.ensure to asynchronously load the necessary javascript to render a certain page. React Router supports this very well.
Is there any equivalent in clojurescript without making multiple html files and each giving it the right script tag with the splitted code through google closure modules?
Sadly I don't have a concrete example yet, and I agree that webpack and react-router make this really easy. There are some links that may direct you to get it working:
Code splitting: http://swannodette.github.io/2015/02/23/hello-google-closure-modules
Manually adding script tags to html files
Actual docs: https://github.com/clojure/clojurescript/wiki/Compiler-Options#modules
Dynamic loading of cljs modules: https://rasterize.io/blog/cljs-dynamic-module-loading.html
Uses multi-methods for route definitions to dynamically add implementations when loading more code
Dense read, there is no easy tooling regarding this use case right now, but the article has all clues to get it working
I hope this helps. If you get around to implementing this in an OSS example it would be great if you could share the link.

Refreshing a single component in a JSP page

Can I refresh a HTML component in JSP? I have two dropdowns. On selection of a value in the first dropdown the values in the dropdown box are to be fetched from the database. Is this possible using JSP?
First, JSP is just a view technology which provides a template to write HTML/CSS/JS in and offers facilities to interact with backend Java code using taglibs (like JSTL) and expression language (those ${} things). JSP runs at the server machine, produces a HTML page and sends it to the client side (if you rightclick page and view source in webbrowser, then you should not see any line of Java/JSP code if it has done its work right). JSP does not run at the client machine and can therefore not be directly used to do partial updates in the HTML page.
To achieve what you want, you need to use JavaScript to fire an asynchronous HTTP request (also known as the Ajax technique) to retrieve the data and manipulate the HTML DOM tree accordingly to add the new elements. Since methods to fire Ajax requests and manipulate the HTML DOM may differ among webbrowsers, I strongly recommend to pick the jQuery JavaScript library to keep it concise and simple without any worries about functioning in different webbrowsers.
I've posted an answer in detail about this before, check solution #3 in this answer.