React

时间:2017-11-10 13:19:32

标签: reactjs redux globals

我知道Redux解决了这个问题,但我提出了一个想法。

想象一下,我有一个应用程序在启动时获得一些JSON。基于此JSON,我设置了环境,因此我们假设应用程序启动并下载一系列列表项。

当然,因为我没有使用Redux(应用程序本身非常简单,Redux在这里感觉像是一个巨大的矫枉过正)如果我想在我的组件之外使用这些列表项,我必须将它们作为道具传递下来然后再将它们作为道具再次传递给我想要使用它们。

为什么我不能这样做:

fetch(listItems)
  .then(response => response.json())
  .then(json => {
    window.consts = json.list;

这样我就可以在我的应用程序的任何地方访问我的列表,甚至可以在React之外。它被认为是一种反模式吗?当然,WON的列表项会被改变,因此没有交互或状态的变化。

3 个答案:

答案 0 :(得分:1)

React 的角度来看:

您可以通过Context从顶层传递列表,然后您可以看到文档here

使用它的示例很简单,存在于许多库中,例如Material UI components使用它来为所有组件注入主题。

的工程概念来看,一切都是的交易:

如果你觉得它会花费那么多时间,而你永远不会改变它,那么保持简单,将其设置为window并记录下来。 (为了你自己不要忘记它并让其他人知道你为什么这样做。)

答案 1 :(得分:1)

如果您绝对肯定他们不会改变,我认为将它们存储在全局中是非常好的,特别是如果您需要访问React之外的数据。您可能想要使用其他名称,例如" appNameConfig" ..

否则,React有一个名为Context的功能,它也可以用于" deep provision" - Reference

答案 2 :(得分:1)

当我有一些静态(但通过API请求)数据时,我通常会做的是一种小型服务,它像全局一样,但是经常导入:

// get-timezones.js
import { get } from '../services/request'

let fetching = false
let timez = null
export default () => {
  // if we already got timezones, return it
  if (timez) {
    return new Promise((resolve) => resolve(timez))
  }

  // if we already fired a request, return its promise
  if (fetching) {
    return fetching
  }

  // first run, return request promise
  // and populate timezones for caching
  fetching = get('timezones').then((data) => {
    timez = data
    return timez
  })
  return fetching
}

然后在视图中反应组件:

// some-view.js
getTimezones().then((timezones) => {
  this.setState({ timezones })
})

这种工作方式总会返回一个promise,但第一次调用它时,它会向API发出请求并获取数据。后续请求将使用缓存变量(有点像全局变量)。

您的方法可能有一些问题:

  • 如果在填充此window.consts之前进行了反应,则您不会获胜 能够访问它,反应不知道它应该重新渲染。
  • 即使没有使用数据,您似乎也在执行此请求。

我的方法唯一的缺点是异步设置状态,如果组件不再安装,可能会导致错误。