Javascript 如何在React应用程序中避免全局状态?

Javascript 如何在React应用程序中避免全局状态?,javascript,dependency-injection,reactjs,global-variables,global-state,Javascript,Dependency Injection,Reactjs,Global Variables,Global State,在我的React应用程序中,我需要存储一些几乎在任何地方都可以访问的数据,但我不想将其保存在全局(即静态)数据结构中,这样就很容易模拟我的单元测试和样式指南 我指的数据是,例如: 浏览器中的常量,在浏览器中为true,在节点中为false 常量是\u MOBILE,在浏览器中启动时初始化 当前登录的用户的数据 我连接到的API的url(它是本地主机、临时服务器或生产,具体取决于配置) 现在我有一个名为sessionData.js的文件来存储这些数据,每当我需要时,我都会在代码中要求('./s

在我的React应用程序中,我需要存储一些几乎在任何地方都可以访问的数据,但我不想将其保存在全局(即静态)数据结构中,这样就很容易模拟我的单元测试和样式指南

我指的数据是,例如:

  • 浏览器中的常量
    ,在浏览器中为
    true
    ,在节点中为
    false
  • 常量
    是\u MOBILE
    ,在浏览器中启动时初始化
  • 当前登录的用户的数据
  • 我连接到的API的url(它是本地主机、临时服务器或生产,具体取决于配置)
现在我有一个名为
sessionData.js
的文件来存储这些数据,每当我需要时,我都会
在代码中要求('./sessionData')
。我可以使用
rewre
模拟它进行单元测试,当它们按顺序运行时,它目前运行良好。styleguide有问题,因为每个示例都可以从不同用户的角度显示视图(因此理想情况下每个示例都有自己的
sessionData

浏览器中的
目前是一个
全局的
,这也是一个坏主意,因为它隐含了对每个模块初始化代码的依赖

我看到我可以通过道具将我的
sessionData
和其他东西传递给层次结构中的每个组件,但这似乎有很多冗余


有什么设计模式可以更好地解决这个问题吗?

我使用Webpack,有一个名为
DefinePlugin
的插件可以处理这个问题。 我想这是一个很好的实践,因为它是我放置大多数应用程序配置详细信息的地方

例如,我的网页包配置有:

new webpack.DefinePlugin({
  'process.env': {'NODE_ENV': JSON.stringify(options.env)}
}),
因此,我可以在前端使用
process.env.NODE\u env
,就像在后端一样

我在这里打开了我的网页配置:

这里有一个

对于单元测试,我使用一个定义一些全局变量的
testhelper.js
类,并且在每次测试开始时都需要它。我不确定这是否是一个好的实践,但对我们的项目来说效果很好。我们在没有网页的情况下运行测试。也许更好的做法是为处理这些全局变量的测试提供一个特定的Web包配置。

看起来是一种方法


不幸的是,API目前不稳定,例如,
React。withContext
在0.13-alpha中被弃用,文档说API将来会改变,但似乎上下文本身就是这样。

如果我理解正确,为什么不通过道具将数据结构传递到所有可能需要它的组件中呢?显然,您不能通过道具对其进行修改,但在该数据结构中,您始终可以包含一个回调函数来更新它,其结构如下:

structure = {
  dataItem1: stuff,
  dataItem2: stuff2,
  dataItemCallback: { var foo = stuff here; }
}
您可以这样称呼它:

this.props.structure.dataItem1;
this.props.structure.dataItem2;
要更新您随时可以调用的内容,请执行以下操作:

this.props.structure.dataItemCallback(newData);

此外,如果您通过道具传递数据,现在如果结构发生任何变化,所有组件都可以重新加载。

在某些情况下,可以重构组件以直接传递所需的数据,而不是使其处于全局状态。这并不能解决问题,但可以显著减少问题。这里有一个:


这一个很好,但它只对第一种情况有用,即浏览器中的
常量。@m01我想你可以在插件中添加另一个参数,指向你的
sessionData.js
模块,这样你就可以使用它,而无需每次都使用它。但是您必须返回一个函数,而不是一个构造的对象。不确定它是否合适。sessionData的问题是我不希望它是全局的。我想为每个单元测试或每个styleguide示例动态地更改它。这似乎是一个好主意,但我担心结构会越来越大(因此更难模拟或维护)。你能详细说明一下如何保持它的简单性和可维护性吗?我不得不说,如果视图不得不如此担心结构,那么视图组件可能太复杂了。在视图级别,组件应该只是获取道具,并在没有任何逻辑的情况下渲染它们。视图控制器可能有一些额外的逻辑来处理数据结构的所有部分到达的位置,并通过道具将它们单独传递给哑视图组件。如何使结构简单且易于维护?我想这一切都取决于你的个人需要:)