161

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

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

4

11 回答 11

100

超越反应

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

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

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/adoring-architecture-ru3vt (参见 UserContext.tsx)

如果使用 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

于 2019-04-11T03:42:15.277 回答
71

你为什么不尝试使用Context

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

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

正如在编写清晰的代码时最好避免使用全局变量一样,在大多数情况下您应该避免使用上下文。特别是,在使用它来“节省打字”并使用它而不是传递显式道具之前要三思而后行。

于 2015-12-18T10:52:54.040 回答
37

不推荐,但是....您可以使用应用程序类中的 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

于 2016-06-10T11:51:07.910 回答
29

在 ./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
于 2020-02-07T19:11:20.767 回答
8

globalThis这是我们为React Native应用程序采用的现代方法。

globalThis现在包含在...


appGlobals.ts

// define our parent property accessible via globalThis. Also apply the TypeScript type.
var app: globalAppVariables;

// define the child properties and their types. 
type globalAppVariables = {
  messageLimit: number;
  // more can go here. 
};

// set the values.
globalThis.app = {
  messageLimit: 10,
  // more can go here.
};


// Freeze so these can only be defined in this file.
Object.freeze(globalThis.app);


App.tsx(我们的主要入口点文件

import './appGlobals'

// other code


anyWhereElseInTheApp.tsx

const chatGroupQuery = useQuery(GET_CHAT_GROUP_WITH_MESSAGES_BY_ID, {
  variables: {
    chatGroupId,
    currentUserId: me.id,
    messageLimit: globalThis.app.messageLimit, //  used here.
  },
});
于 2020-05-30T17:59:33.383 回答
7

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

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

在 js 模块中可以读为

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

希望这会有所帮助。

于 2018-11-29T06:55:38.543 回答
5

到目前为止,我发现的最好方法是使用React Context,但将其隔离在高阶提供程序组件中。

于 2016-12-16T10:36:51.857 回答
3

您可以在 react https://facebook.github.io/react/docs/reusable-components.html#mixins中使用 mixins 。

于 2015-12-19T12:08:42.010 回答
0

也许它正在使用大锤来破解坚果,但使用环境变量(使用 Dotenv https://www.npmjs.com/package/dotenv)您还可以在整个 React 应用程序中提供值。并且在使用它们的地方没有任何开销代码。

我来到这里是因为我发现在我的 env 文件中定义的一些变量在不同的 env 中都是静态的,所以我寻找一种将它们移出 env 文件的方法。但老实说,我不喜欢我在这里找到的任何替代品。我不想每次需要这些值时都设置和使用上下文。

我在环境方面没有经验,所以如果这种方法有缺点,请告诉我。

于 2021-01-13T15:44:04.887 回答
0

GlobalThis 可能在某些浏览器中受支持。
您可以参考以下链接
https://webpack.js.org/plugins/provide-plugin/
https://webpack.js.org/plugins/define-plugin/

于 2021-01-12T13:24:19.193 回答
-8

我不知道他们想用“React Context”的东西说什么——他们对我说的是希腊语,但我是这样做的:

在同一页面上的函数之间携带值

在您的构造函数中,绑定您的设置器:

this.setSomeVariable = this.setSomeVariable.bind(this);

然后在构造函数下方声明一个函数:

setSomeVariable(propertyTextToAdd) {
    this.setState({
        myProperty: propertyTextToAdd
    });
}

当你想设置它时,调用this.setSomeVariable("some value");

(你甚至可以逃脱this.state.myProperty = "some value";

当你想得到它,打电话var myProp = this.state.myProperty;

使用alert(myProp);应该给你some value

跨页面/组件携带值的额外脚手架方法

您可以将模型分配给this(技术上this.stores),因此您可以使用以下方式引用它this.state

import Reflux from 'reflux'
import Actions from '~/actions/actions'

class YourForm extends Reflux.Store
{
    constructor()
    {
        super();
        this.state = {
            someGlobalVariable: '',
        };
        this.listenables = Actions;
        this.baseState = {
            someGlobalVariable: '',
        };
    }

    onUpdateFields(name, value) {
        this.setState({
            [name]: value,
        });
    }

    onResetFields() {
        this.setState({
           someGlobalVariable: '',
        });
    }
}
const reqformdata = new YourForm

export default reqformdata

stores将其保存到名为yourForm.jsx.

然后您可以在另一个页面中执行此操作:

import React from 'react'
import Reflux from 'reflux'
import {Form} from 'reactstrap'
import YourForm from '~/stores/yourForm.jsx'

Reflux.defineReact(React)

class SomePage extends Reflux.Component {
    constructor(props) {
        super(props);
        this.state = {
            someLocalVariable: '',
        }
        this.stores = [
            YourForm,
        ]
    }
    render() {

        const myVar = this.state.someGlobalVariable;
        return (
            <Form>
                <div>{myVar}</div>
            </Form>
        )
    }
}
export default SomePage

如果您this.state.someGlobalVariable使用以下功能在另一个组件中设置:

setSomeVariable(propertyTextToAdd) {
    this.setState({
       myGlobalVariable: propertyTextToAdd
   });
}

你在构造函数中绑定:

this.setSomeVariable = this.setSomeVariable.bind(this);

使用上面显示的代码propertyTextToAdd将显示 in 中的值。SomePage

于 2017-10-14T07:26:51.950 回答