如何在 React 中声明一个全局变量?

IT技术 reactjs javascript-globalize
2021-04-02 04:53:08

i18n在一个组件(在 app 中加载的第一个组件)中初始化了一次翻译对象。在所有其他组件中都需要相同的对象。我不想在每个组件中重新初始化它。有什么办法?使其可用于窗口范围无济于事,因为我需要在render()方法中使用它

请为这些问题提出一个通用的解决方案,而不是 i18n 特定的解决方案。

6个回答

超越react

您可能不知道导入已经是全局的如果您导出对象(单例),则它可以作为导入语句全局访问,也可以全局修改

如果你想全局初始化一些东西但确保它只修改一次,你可以使用这种最初具有可修改属性的单例方法,但你可以Object.freeze在第一次使用后使用它来确保它在你的初始化场景中不可变

const myInitObject = {}
export default myInitObject

然后在您的 init 方法中引用它:

import myInitObject from './myInitObject'
myInitObject.someProp = 'i am about to get cold'
Object.freeze(myInitObject)

myInitObject仍将是全球性的,因为它可以在任何地方引用为进口,但仍然保持冻结,并抛出,如果有人试图修改它。

我使用单例破解全局状态

https://codesandbox.io/s/react-typescript-playground-forked-h8rpu

如果使用 react-create-app

(我实际上在寻找什么)在这种情况下,您还可以在引用环境变量时干净地初始化全局对象。

在项目的根目录中创建一个带有前缀变量.env文件REACT_APP_非常好。您可以process.env.REACT_APP_SOME_VAR根据需要在 JS 和 JSX 中进行引用,并且它在设计上是不可变的。

这避免了必须window.myVar = %REACT_APP_MY_VAR%在 HTML 中设置

直接从 Facebook 查看更多有用的详细信息:

https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables

这个真的很有帮助,谢谢分享。
2021-05-25 04:53:08
这是迄今为止最好的答案!
2021-05-26 04:53:08
伙计,这让我大开眼界……谢谢你,从现在开始我想我会比 FE 开发者好 20% :P
2021-05-31 04:53:08
哇!这非常优雅简单。谢谢分享,杰森!
2021-06-02 04:53:08
老实说,这是一个很好的提示,因为我使用的是服务器端渲染,所以我的身份验证令牌有问题。我最终在第一次加载时从 localstorage 加载,然后将其存储到我可以导入的单独配置文件中。很好的答案。
2021-06-13 04:53:08

为什么不尝试使用Context

您可以在任何父组件中声明一个全局上下文变量,并且可以通过this.context.varname. 您只需要在父组件中指定childContextTypesgetChildContext,然后只需contextTypes在子组件中指定即可从任何组件使用/修改它

但是,请注意文档中提到的这一点:

正如在编写清晰的代码时最好避免使用全局变量一样,在大多数情况下您应该避免使用上下文。特别是,在使用它来“保存输入”并使用它而不是传递显式props之前,请三思。

关闭 。但是所有组件都没有父子关系,并且 Context 不能在该树之外工作。我想要跨应用程序的 i18n。
2021-06-01 04:53:08
@sapy 这就是为什么你应该使用 i18n 作为 redux 状态而不是上下文变量,请参阅我的答案:stackoverflow.com/questions/33413880/...
2021-06-01 04:53:08
在我看来,我建议改用 redux,特别是对于大型应用程序
2021-06-01 04:53:08
警告:这样的答案可能会触发 redux 专家。
2021-06-01 04:53:08

不推荐但是....您可以使用您的应用程序类中的 componentWillMount 通过它添加您的全局变量...有点像这样:

componentWillMount: function () {
    window.MyVars = {
        ajax: require('../helpers/ajax.jsx'),
        utils: require('../helpers/utils.jsx')
    };
}

仍然认为这是一个黑客......但它会完成你的工作

顺便说一句, componentWillMount 在渲染前执行一次,在此处查看更多信息:https : //reactjs.org/docs/react-component.html#mounting-componentwillmount

对于某些用例,这是一个黑客。我正在将一个 React 应用程序集成到我公司的另一个非 React 应用程序的上下文中。这似乎是为消费应用程序公开公共方法的好方法。我错了吗?有没有更好的办法?
2021-05-24 04:53:08
@mccambridge 我知道这已经晚了,但我会从非 React 应用程序向 React 发送一个函数,您可以调用它来发送信息。顺便说一句,你可以用 iframe 来做到这一点。
2021-06-01 04:53:08
另请注意,componentWillMount已弃用:reactjs.org/blog/2018/03/27/update-on-async-rendering.html
2021-06-07 04:53:08

在 ./src 文件夹中创建一个名为“config.js”的文件,内容如下:

module.exports = global.config = {
    i18n: {
        welcome: {
            en: "Welcome",
            fa: "خوش آمدید"
        }
        // rest of your translation object
    }
    // other global config variables you wish
};

在你的主文件“index.js”中加入这一行:

import './config';

在任何需要对象的地方都使用这个:

global.config.i18n.welcome.en

可以在 webpack ie 中保留全局变量 webpack.config.js

externals: {
  'config': JSON.stringify(GLOBAL_VARIABLE: "global var value")
}

在 js module中可以这样读

var config = require('config')
var GLOBAL_VARIABLE = config.GLOBAL_VARIABLE

希望这会有所帮助。