我i18n
在一个组件(在应用程序中加载的第一个组件)中初始化了翻译对象。所有其他组件都需要相同的对象。我不想在每个组件中重新初始化它。怎么回事?使它可用于窗口范围并没有帮助,因为我需要在render()
方法中使用它。
请提出针对这些问题的通用解决方案,而不是针对国际化的解决方案。
我i18n
在一个组件(在应用程序中加载的第一个组件)中初始化了翻译对象。所有其他组件都需要相同的对象。我不想在每个组件中重新初始化它。怎么回事?使它可用于窗口范围并没有帮助,因为我需要在render()
方法中使用它。
请提出针对这些问题的通用解决方案,而不是针对国际化的解决方案。
Answers:
为什么不尝试使用Context?
您可以在任何父组件中声明一个全局上下文变量,并且可以通过整个组件树访问此变量this.context.varname
。您只需要在父组件中指定childContextTypes
,getChildContext
然后就可以通过contextTypes
在子组件中进行指定而在任何组件中使用/修改它。
但是,请注意文档中提到的这一点:
正如在编写清晰的代码时最好避免使用全局变量一样,在大多数情况下也应避免使用上下文。特别是,在使用它“保存类型”并使用它而不是传递显式道具之前,请三思。
您可能不知道导入已经是全局的。如果导出对象(单个),则可以将其作为导入语句全局访问,也可以全局修改。
如果要全局初始化某件事,但确保仅对其进行一次修改,则可以使用这种最初具有可修改属性的单例方法,但是Object.freeze
在首次使用后可以使用它来确保其在初始化方案中不可变。
const myInitObject = {}
export default myInitObject
然后在您的init方法中引用它:
import myInitObject from './myInitObject'
myInitObject.someProp = 'i am about to get cold'
Object.freeze(myInitObject)
由于myInitObject
仍可以是全局引用,因此可以在任何地方将其作为导入引用,但是如果有人尝试对其进行修改,它将保持冻结并抛出。
(实际上我在找什么)在这种情况下,您还可以在引用环境变量时干净地初始化全局对象。
在项目的根目录中创建一个带有前缀变量的.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
不推荐,但是...。您可以从应用程序类中使用componentWillMount来通过它添加全局变量...有点像这样:
componentWillMount: function () {
window.MyVars = {
ajax: require('../helpers/ajax.jsx'),
utils: require('../helpers/utils.jsx')
};
}
仍然认为这是一个骇客...但是它将完成您的工作
btw componentWillMount在渲染之前执行一次,请在此处查看更多信息:https : //reactjs.org/docs/react-component.html#mounting-componentwillmount
componentWillMount
已被弃用:reactjs.org/blog/2018/03/27/update-on-async-rendering.html
使用以下内容在./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
到目前为止,我发现的最好方法是使用React Context,但将其隔离在高阶提供程序组件中。
您可以在react https://facebook.github.io/react/docs/reusable-components.html#mixins中使用mixins 。
这是一种现代方法,使用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.
},
});
我不知道他们想用这种“反应上下文”的东西说什么-他们在跟希腊人说话,但是这是我的做法:
在同一页上的函数之间携带值
在构造函数中,绑定您的setter:
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
将SomePage
使用上面显示的代码显示。
Redux
或Flux
可以全局处理数据或状态的库。您可以轻松地将其传递给所有组件