I'm building all of my pages using the SPA (single page app) approach lately. I have typically been following this general model for doing so:
My page:
<apex:page docType="html-5.0" showHeader="true" sideBar="true" standardController="TheStandardController" extensions="TheExtension">
<script>
window.__APEX_VARS__ = {
//...throw any one-off merge fields in this object literal I might need in my app, since in a resource file I can't use merge fields.
//I'm usually throwing this in constants.js and just doing export const APEX = window.__APEX_VARS__; so anywhere in my react components I can just import {APEX} from '../lib/constants';
};
</script>
<div id="ContainerForMyApp"></div>
<script src="{!URLFOR($Resource.TheApp)}"></script>
</apex:page>
This works perfectly fine, but I've been struggling with identifying the cleanest way to get any data or config from "TheExtension.cls" (my apex controller extension). I've tried the following approaches:
- Remote Actions These work just fine, but I'm coming across a few caveats. Has anyone experienced these? If so, what was your solution?
Let's say my "MyApp.Resource" is JavaScript, and I'm going to include a bit of React since I'm working with that right now. Generally, the MyApp script might look something like this:
import React, {Component} from 'react'; window.React = React;
import ReactDOM from 'react-dom';
Visualforce.remoting.Manager.invokeAction("TheExtension.TheMethod", ...args, (result, event) => {
ReactDOM.render(
<App
props={result} //You get the idea, stuff from the result of the remote action is needed to render the "App" component.
/>,
document.getElementById("ContainerForMyApp")
);
});
There are a few problems I've noticed with this approach: sometimes "Visualforce" is undefined on page load. Other times, it isn't and I'm not sure the reason for that. The second issue is the obvious one, that the "App" component won't be rendered until the async remote action returns a result of some kind.
Has anyone done this and used redux or another similar state management architecture to render the page, and then have the data and config populate once it's retrieved from the server? Is there an alternative to using remote actions that I may have overlooked?