如何从外部反应中获取变量

时间:2017-02-27 18:24:47

标签: javascript reactjs redux

我需要获取放在反应容器之外的变量的值。

<body>
    <div id='react-app'></div>

<script>
    var _variable = 3
</script>

</body>

我需要在react-component中取这个值,如果可能的话,将这个值存储在Store(redux)中

3 个答案:

答案 0 :(得分:3)

如果您将声明脚本放在react-load脚本之前,则react脚本应该能够访问它。

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

答案 1 :(得分:2)

Redux在配置存储时有一个api来水合减速器。 createStore方法的签名是:

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

这意味着您可以将configureStore方法定义为:

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);
}

然后在您的条目文件(例如index.js或类似文件)中,您将包含configureStore并在传递用户详细信息时调用它:

const store = configureStore({
  reducerA: {...},
  reducerUserDetails: window.userDetails || {},
});

ReactDOM.render(
  <Provider store={store}>
    <YourApp />
  </Provider>,
  document.getElementById('react-app'),
);

答案 2 :(得分:2)

这是一系列技术方法的有趣挑战。

的Singleton

对于大多数开发人员而言最简单的方法正在利用 ES6模块是单例这一事实。这意味着您可以在一个模块中配置一个对象,然后在另一个模块中将导入并知道该值将是相同的

话虽如此,我们可以在启动应用程序时轻松传入变量。

为什么不使用全局变量?你肯定可以引入全局变量并将它称为一天,但那将是ES6试图建立的反模式。这是why to avoid global variables in JS

的一个很好的演练

那么,我们怎么能这样做呢?

让我们在启动React App

时进行控制

首先,将reactDom.render()包裹在一个函数中:

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')
    );
}

所以对于那些使用react和ES6的人来说,这应该是相当熟悉的。我们在这里所做的就是将它包装在一个绑定到window对象的函数中,以便它可以在外部JS中使用。

现在,初始化您的反应应用现在看起来应该是这样的:

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

那么,我们如何将变量传递给它?你们中的一些人可能已经猜到了:)我们已经设置我们的应用程序通过其参数接受变量:

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

在我们的HTML中

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

Redux怎么样?

如果我们想将它添加到道具中,这样可以正常工作,当然,当我们使用更大的应用程序时,我们会使用带有redux的商店。这样的方式更加明智。所以这就是利用ES6中单例对象的那一点。

创建默认商店模块

让我们创建一个新文件,用于存储商店的默认值。我们称之为defaultStore.js

let defaultStore = {
        item: "one",
        other: "two"
    }

export default (defaultStore);

现在,让我们将它介绍给我们的reducer:

import defaultStore from "path/to/defaultStore.js"

export default function app( state = defaultStore, action ) {

    switch (action.type) {
        //...
    }

    return state;
}

回到我们之前构建的函数,我们包含默认存储:

...    
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')
    );
}

由于app 的这一部分将在应用呈现之前调用,因此我们会在构建主商店之前改变默认商店。

还有一次让我们来看看HTML中的js

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

这就是诀窍!您甚至可以通过这种方式设置整个外部商店,或创建一个您想要的奇特合并对象巫术。