I was trying to pass config variables from a backend written in Go to a single page app (SPA) written in react. For example, I wanted to set an "Env" flag to dev
or prod
or control whether you have to log in or not. Here's an example of the /api/config
route that supplies this data:
{
"Auth0ClientDomain": "odewahn.auth0.com",
"Auth0ClientID": "gcSxq9GfpUdVWNIvYiOsP7rh1s8u6ftA",
"ClientBrowser": "HTTPie",
"ClientOS": "darwin",
"Env": "dev",
"FirstClientLoad": "true",
"HomeDir": "/Users/odewahn",
"HostCount": 0,
"HostFileName": ".launchbot.yml",
"LaunchbotEndpoint": "http://launchbot.io",
"RequireLogin": true,
"UserMode": "free",
"Version": "0.1.4",
"WelcomeMessageVisible": true,
"WelcomeVideoYouTubeID": "xUGwz0A6eKU"
}
This is pretty common thing, and while it's easy in most server side contexts where you can just dump these things right into the page, it took me a while to make it work in the React/Redux single page app world. Although the API supplied the results accurately, the frontend would load and display, and only then load the config information. So, actions I wanted to trigger weren't being set correctly.
I finally figured out a simple workaround: use fetch to wrap the call to ReactDOM.render
in a promise chain so that you render the page app only after you're gotten the results back and dispatched the action to load the config values into the state tree:
fetch('/api/config')
.then( response => {
return response.json()
})
.then( config => {
store.dispatch(setConfig(config))
})
.then( () => {
ReactDOM.render(
<Provider store={store}>
<Router>{routes}</Router>
</Provider>,
document.getElementById('app')
)
})