2016-02-26 69 views
1

在用Redux,flux和其他pub/sub方法挣扎太多之后,我用以下技术结束了。我不知道这是否会造成一些大的损害或缺陷,因此将其张贴在此处,以便从有经验的程序员那里了解其优点和缺点。Reactjs组件之间的通信

var thisManager = function(){ 

    var _Manager = []; 
    return{ 
     getThis : function(key){ 
      return _Manager[key]; 
     }, 
     setThis : function(obj){    
      _Manager[obj.key] = obj.value; 
     } 
    } 
}; 
var _thisManager = new thisManager(); 

// React Component 
class Header extends Component{ 
    constructor(){ 
     super(); 
     _thisManager.setThis({ key: "Header", value:this} 
    } 
    someFunction(data){ 
     // call this.setState here with new data. 
    } 
    render(){ 
     return <div /> 
    } 
} 

// Then from any other component living far somewhere you can pass the data to the render function and it works out of the box. 
i.e. 

class Footer extends Component{ 
    _click(e){ 
    let Header = _thisManager.getThis('Header'); 
    Header.somefunction(" Wow some new data from footer event "); 
    } 
render(){ 
     return(
     <div> 
      <button onClick={this._click.bind(this)}> send data to header and call its render </button> 
     </div> 


    ); 
    } 
} 

我送JSON在我的应用程序中的数据并将其完美呈现所需的成分,我可以调用渲染没有任何的pub/sub或深传承道具来调用父类的方法以改变该.setState导致重新渲染。

到目前为止,该应用程序工作正常,我也爱它的简单了。请扔光这种技术的优点和缺点

问候

编辑:

它是坏的调用渲染,所以我改成了另一种方法来获得这种设置的更多优点和缺点。与此设置

+1

尽管这种方式在一个非常有限的用例(如您提供的示例)中起作用,但会干扰反应组件的生命周期。渲染方法决不是直接调用,也不应该有输入,这使得它不纯。至少,揭露一种不同的公共方法,它接受你发送的任何内容。在该方法中,执行setState将隐式地调用渲染。最后,而不是渲染调用该方法。 – hazardous

+0

谢谢@HazardouS,肯定是正确的,但技术怎么样,基本上我没有公开它是可以调用渲染的引用,我猜setState会做同样的效果加上什么损坏的部分发送数据渲染函数作为参数? –

+0

SO应用程序不是很好的长期解释:)。请阅读React中的纯渲染方法假设。 React批处理渲染,这就是为什么它不应该直接调用。 – hazardous

回答

1

两个主要关注点:
1.你不应该做出响应的生命周期方法直接
2.后门进入组件是一个坏主意,这破坏反应的可维护性

广告1 : 如果您直接调用render()(或任何其他反应方法),则可能不会在组件树中调用componentDidMount(),componentDidUpdate()和其他生命周期方法。

危险是:

  • 许多设计与反应成分在很大程度上依赖于生命周期方法被解雇:getInitialState()componentWillReceiveProps()shouldComponentUpdate()componentDidMount(),等等等等,如果你直接调用render(),许多组件可能会破坏或显示奇怪的行为。
  • 您冒着破坏反应的差异引擎的风险:通过生命周期管理,反应在其内部存储器中保留虚拟副本。为了正确工作,如果对反应的工作至关重要,则该副本的完整性。

更好的方式是(但仍然违反了我的第二个点):

  • 包括组件内的不同方法。
  • 如果要重新渲染,其中有一个setState()
  • 并从外部调用该方法。

广告2. 的直接引用一个安装部件(作为thisManager确实)具有一些额外的风险。 React的设计和局限性是有原因的:保持道具和状态的单向流和组件层次结构,使事情易于维护。

如果你打破这种模式 - 通过在组件中构建后门,允许操纵状态 - 你打破了这种设计原则的反应。这是一个快速的捷径,但是当您的应用程序增长时肯定会造成很大的痛苦和沮丧。

据我所知,此规则的唯一可接受的例外是:

一个组件内
  • 中的方法,以Ajax调用的结果作出反应,更新状态
  • (如获取来自服务器的数据后)一个组件内的方法来处理(在形式,例如运行验证一个孩子按钮被点击后)从它的直接后代子组件触发

所以,如果你想使用它的目的,那么你应该罚款。 警告字:标准反应方法警卫随机访问组件,因为调用组件或方法需要引用组件。在这两个例子中,这样的参考是可用的。
在你的设置中,任何一段外部代码都可以查找表格中“标题”的引用,并调用更新状态的方法。 有了这样的间接引用,并且没有办法告诉哪个源实际称为你的组件,你的代码很可能变得更难以调试/维护。

+0

感谢@wintvelt,所以任何其他方法,只是可以造成this.setState将罚款? –

+0

不完全,请参阅我的第二点。 – wintvelt

+0

正确的感谢,我编辑了这个问题,现在想知道为什么会这样做,因为我基本上我想要的是用新的数据重新组件,所以最后一件事就是订阅一些事件并做它,因为我发现容易的是然后发布一个事件我发送数据直接到我的功能,可以做到这一点.setState?你说什么? –