React: Singleton React组件

创建于 2015-11-27  ·  5评论  ·  资料来源: facebook/react

大家好!
因此,在此应用程序中,我正在编写一个名为“帮助部分”的组件。 基本上,它是一个框,显示一些与用户混淆的组件有关的预定义文本。

我希望能够告诉我的“帮助部分”组件为哪个组件显示帮助。 到目前为止,我正在将Flux与一些动作和商店一起使用。 这还不错,并且效果很好,但是它是一个很大的设置,为此专门定义了2个文件。 我还遇到了许多其他问题,例如由于其他动作而导致的“帮助部分”动作分配(这会引发“无法在分配过程中进行分配”错误)。

但是,如果我可以将“ help section”定义为单例,则只需import helpSection from './HelpSection并完成它,因为我将获得“ help section”的实例。 我要做的就是在helpSection上公开一个方法,该方法设置要更改的属性并调用它。

我知道它破坏了React的单向数据流,其中一个组件更改了另一个组件,但是有时值得这样做。 我的想法是将商店,一些动作和一个组件组合成一个对象。 许多组件在运行时只会实例化一次,因此在某些情况下它可能会非常有用。

除了此JSfiddle之外,我在网上找不到任何

我是JavaScript和React的新手,所以我可能会遗漏一些明显的观点,希望不会。
你怎么看待这件事?
谢谢阅读。

(PS很抱歉造成歧义,英语不是我的母语...:smile :)

Question

最有用的评论

您好@all

我想通过增加另一种观点来使这次对话恢复活力。 通过react @ 16 ,可以使用Portal将组件安装到DOM的某些点。 对于此用例,我正在构建不同的组件,如模式或通知,这些组件应呈现为在我的App.jsx安装的某个其他组件,如下所示。

App.jsx

[...]
render() {
  return (<SingletonOverlay></SingletonOverlay>)
}
[...]

Notification.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import NotificationComponent from './Notification.js';
import SingletonOverlay from '../general/Overlay.js';

export default class Notification extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      element: null
    };
  }

  componentDidMount() {
    this.setState({ element: ReactDOM.findDOMNode(SingletonOverlay) });
  }

  render() {
    return this.state.element
      ? ReactDOM.createPortal(
        <NotificationComponent>That is a notification</NotificationComponent>,
        this.state.element,
      )
      : null;
  }
}

另一种选择是找到具有document.findElementById或类似功能的domNode并将它们传递给ReactDOM.findDOMNode ,这使我感到非常不愉快,因为我被迫离开了“ React-Cosmos”。

因此,我希望能够搜索传递给函数的某个组件的实例,而不是为上述功能传递实例本身。 我也对解决该问题的其他方法感兴趣。

@jimfb这值得一个功能建议吗?

所有5条评论

这看起来像一个使用问题,而不是React内核中的错误。 在我们尝试使用github问题来跟踪React核心中的错误时,在StackOverflow之类的网站上可以更好地回答使用问题。 出于这个原因,我将结束这个问题,但是请随时在此处继续讨论或将其移至StackOverflow。

关于您的问题,我个人的建议是避免单身。
http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons

谢谢回复。
是否已经有一种方法可以将React组件创建为我不知道的单例? (我不信任JSfiddle,直到您的一位前辈对其进行评估为止)。 如果有,请与我分享,因为我在文档中找不到任何有关它的信息。

“组件之间通信”文档页面中

要在没有父子关系的两个组件之间进行通信,可以设置自己的全局事件系统。
...
助焊剂模式是解决此问题的一种可能方法。

如您所见,没有提到单例。 在您提供的StackOverflow链接中,实际上很多人说使用单例在某些情况下很有用。 从第二个答案:

单例解决一个(并且只有一个)问题。
资源争用。
如果您有一些资源
(1)只能有一个实例,并且
(2)您需要管理单个实例,
您需要一个单身人士。

这听起来像我的用例(在React世界中还有很多用例)。

我认为这在GitHub上仍然是一个问题,因为它似乎是使用组件的一种相关方式,并且我认为文档中应该包含对此的引用。

React组件实例具有内部状态,需要知道该实例在树内的位置。 您不能在多个位置渲染同一实例。 因此,在React世界中,单例实例的想法没有意义。

小提琴中显示的并不是我真正称呼为单例的原因,主要是因为有单实例参数-它更像是具有自己状态的模块。 然后,在渲染实例时,它使用封闭的(但实际上是“全局”)状态。 它在全局状态下欺骗并存储对已安装实例的引用,并强制对已安装实例进行更新。 现在没有任何实际阻止您渲染更多这些内容,这将导致第一个不被更新。 您可以轻松地执行类似的操作并支持渲染多于1。

至于我们在文档中对此进行引用,则不会这样做。 React可以实现很多模式,但是我们不会讨论所有这些模式。

詹姆斯,感谢您抽出宝贵的时间回复。
首先,我完全理解您的观点,并感谢您研究了JSfiddle。 让我发表最后的声明。

  1. 我所说的“单个”是React组件的一个实例,该组件在整个应用程序中仅渲染一次。 那是我的出发点。 因此,您提到的第一个问题如果渲染多于1个就不会更新,那么问题就不那么重要了。
  2. 我知道“污染”全局名称空间是不受欢迎的,但是作为任何编码方法,它都有它的位置和它的用法。 使用Flux做这种事情由于各种原因(我在一天中努力挣扎)还是有问题的,即使现在我想出的解决方案也不太好(在道具或道具之间“选择”组件)商店)。 使用我描述的方式使用单例可以使此操作变得容易得多。 我认为好处大于弊端。
  3. 您知道有关文档的信息。 我已经使用React大约2个月了,文档在某些时候严重缺乏已经不是什么秘密了。 对我而言,学习使用React既困难又令人困惑。
    该文档当前包含3个有关不具有“家族”关系的组件之间的通信的
    初学者严重依赖于文档,也许列出可以解决各种问题的可能模式是您应该做的确切事情。 我们可以自己深入学习模式,学习哪种工具适合该任务是困难的部分。

我想让对我来说很难的事情变得容易。 我认为这只是几行,可以在将来对初学者有所帮助。

我总是最终发表大量评论。.感谢您坚持我并阅读。 :微笑:

您好@all

我想通过增加另一种观点来使这次对话恢复活力。 通过react @ 16 ,可以使用Portal将组件安装到DOM的某些点。 对于此用例,我正在构建不同的组件,如模式或通知,这些组件应呈现为在我的App.jsx安装的某个其他组件,如下所示。

App.jsx

[...]
render() {
  return (<SingletonOverlay></SingletonOverlay>)
}
[...]

Notification.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import NotificationComponent from './Notification.js';
import SingletonOverlay from '../general/Overlay.js';

export default class Notification extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      element: null
    };
  }

  componentDidMount() {
    this.setState({ element: ReactDOM.findDOMNode(SingletonOverlay) });
  }

  render() {
    return this.state.element
      ? ReactDOM.createPortal(
        <NotificationComponent>That is a notification</NotificationComponent>,
        this.state.element,
      )
      : null;
  }
}

另一种选择是找到具有document.findElementById或类似功能的domNode并将它们传递给ReactDOM.findDOMNode ,这使我感到非常不愉快,因为我被迫离开了“ React-Cosmos”。

因此,我希望能够搜索传递给函数的某个组件的实例,而不是为上述功能传递实例本身。 我也对解决该问题的其他方法感兴趣。

@jimfb这值得一个功能建议吗?

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

krave1986 picture krave1986  ·  3评论

varghesep picture varghesep  ·  3评论

hnordt picture hnordt  ·  3评论

zpao picture zpao  ·  3评论

trusktr picture trusktr  ·  3评论