How to take variable from outside reactjs How to take variable from outside reactjs reactjs reactjs

How to take variable from outside reactjs


If you put the declaration script before the react-loading script, the react script should be able to access it.

<script type="text/javascript">  var x = {{ user_details }};</script><script src="/static/app.js"></script>


Redux has an api to hydrate reducers when configuring store.The signature of createStore method is:

createStore(reducer, [preloadedState], [enhancer])

Meaning that you can define your configureStore method as:

import { createStore, combineReducers, applyMiddleware, compose } from 'redux';import thunk from 'redux-thunk';import reducerA from 'reducers/a'import reducerUserDetails from 'reducers/user-details'export default function configureStore(initialState = {}) {  const reducer = combineReducers({    reducerA,    reducerUserDetails,  });  // If you want to use dev tools  const composeEnhancers =    process.env.NODE_ENV !== 'production' &&    typeof window === 'object' &&    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?      window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose;  const enhancer = composeEnhancers(    applyMiddleware(      thunk // If you want to have async actions    )  );  return createStore(reducer, initialState, enhancer);}

Then in your entry file such as index.js or similar, you would include the configureStore and call it while passing user details:

const store = configureStore({  reducerA: {...},  reducerUserDetails: window.userDetails || {},});ReactDOM.render(  <Provider store={store}>    <YourApp />  </Provider>,  document.getElementById('react-app'),);


This is an interesting challenge with a whole bunch of technical approaches.

Singleton

The simplest approach that will work for most devs is taking advantage of the fact that ES6 modules are singletons. This means that you can configure an object in one module, and import it in another and know that the value will be the same.

That being said, we can easily pass in variables when we initiate the app.

Why not use global variables? You can definitely bring in global variables and call it a day, but then that would be an anti pattern that ES6 is trying to establish. Here's a great walk through on why to avoid global variables in JS

So, how can we do this then?

Lets control when we initiate a React App

First, wrap your reactDom.render() in a function:

import React from 'react'import ReactDOM from "react-dom"import { Provider } from "react-redux"import MyApp from "./pathto/myapp.js"import store from "./pathto/store.js"window.RenderApp = function () {    new ReactDom.render(        <Provider store={store}><MyApp /></provider,           document.getElementById('root_element')    );}

So this should look fairly familiar to those of you who have been working with react and ES6. All we've done here is wrap it in a function that is bound to the window object so that it is available to outside JS.

Now, initializing your react app should now look something like this:

<div id="root_element"></div><script src="path/to/bundle.js></script><script>    window.RenderApp();</script>

So, how do we pass variables into it? Some of you may have guessed it already :) We've set up our app to accept variables through its parameters:

...window.RenderApp = function (outside_variable) {    new ReactDom.render(        <Provider store={store}><MyApp someProp={outside_variable} /></provider,           document.getElementById('root_element')    );}

And in our HTML

...<script>    var x = 72;    window.RenderApp(x);</script>

What About Redux?

So this works fine if we want to add it to the props, of course, when we're using larger apps we use stores with redux. It's just more sane that way. So this is where that bit about taking advantage of singleton objects in ES6 comes into play.

Create A Default Store Module

Lets create a new file that will store the default value for a store. We'll call it defaultStore.js.

let defaultStore = {        item: "one",        other: "two"    }export default (defaultStore);

Now, lets introduce it to our reducer:

import defaultStore from "path/to/defaultStore.js"export default function app( state = defaultStore, action ) {    switch (action.type) {        //...    }    return state;}

Back to our function we build earlier, we include our default store:

...    import defaultStore from "path/to/defaultStore.js"window.RenderApp = function (outside_variable) {    defaultStore.item = outside_variable;    new ReactDom.render(        <Provider store={store}><MyApp /></provider,           document.getElementById('root_element')    );}

Because this portion of the app will be called before the app renders, we are mutating the default store before the main store gets built.

And just one more time lets take a look at the js in the HTML

...<script>    var x = 72;    window.RenderApp(x);</script>

And that does the trick! You can even set entire outside stores this way, or create a fancy merging object witchcraft you want.