简体   繁体   English

Reactjs组件之间的通信

[英]Communication between Reactjs Components

After struggling too much with Redux, flux and other pub/sub methods i ended up with the following technique. 在使用Redux,flux和其他pub / sub方法苦苦挣扎之后,我最终得到了以下技术。 I do not know if that can cause some big damage or flaws so posting it here to get some light from the experienced programmers about its pros and cons. 我不知道这是否会造成较大的损害或缺陷,因此将其发布在此处可以使经验丰富的程序员了解它的优缺点。

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>


      );
  }
}

I am sending json as a data in my application and it perfectly renders the desired components and i can invoke the render without any pub/sub or deep passing down the props to invoke a parent method with a changing this.setState to cause re-render. 我正在将json作为数据发送到我的应用程序中,并且它完美地呈现了所需的组件,并且我可以在没有任何pub / sub的情况下调用呈现器,也不必深入传递道具来调用父方法,而更改this.setState导致重新呈现。

So far the application works fine and i am also loving its simplicity too. 到目前为止,该应用程序运行良好,我也喜欢它的简单性。 Kindly throw light on this technique pros and cons 请简要介绍此技术的优缺点

Regards 问候

EDIT: 编辑:

It is bad to call render so i changed it to another method to get more pros and cons of this setup. 调用render很不好,所以我将其更改为另一种方法以获得此设置的更多优点和缺点。

Two main concerns with this setup: 此设置有两个主要问题:
1. You should never call react lifecycle methods directly 1.永远不要直接调用react生命周期方法
2. Backdoors into components are a bad idea, which destroy react's maintainability 2.组件后门是个坏主意,它会破坏react的可维护性

Ad 1: If you invoke render() (or any other react method) directly, react probably does not call componentDidMount() , componentDidUpdate()` and other lifecycle methods in the component tree. 广告1:如果直接调用render() (或任何其他react方法),react可能不会在组件树中调用componentDidMount() ,componentDidUpdate()和其他生命周期方法。

Dangers are: 危险是:

  • Many designs with react component rely heavily on the lifecycle methods being fired: getInitialState() , componentWillReceiveProps() , shouldComponentUpdate() , componentDidMount() , etc etc. If you call render() directly, many components will likely break or show strange behaviour. 许多具有shouldComponentUpdate() componentWillReceiveProps()设计在很大程度上依赖于触发的生命周期方法: getInitialState()componentWillReceiveProps()shouldComponentUpdate()componentDidMount()等等。如果直接调用render() ,那么许多组件可能会shouldComponentUpdate()或显示奇怪的行为。
  • You run the risk of breaking react's difference engine: through life-cycle management, react keeps a virtual copy of DOM in its (internal) memory. 您冒着破坏React差异引擎的风险:通过生命周期管理,React将DOM的虚拟副本保留在其(内部)内存中。 To work correctly, the integrity of this copy if vital to react's working. 为了正常工作,此副本的完整性(对于响应工作至关重要)。

Better would be (but still in violation of my second point): 更好(但仍然违反我的第二点):

  • Include a different method inside the component. 在组件内部包括其他方法。
  • Which has a setState() if you want to re-render. 如果要重新渲染,则具有setState()
  • And call that method from the outside. 并从外部调用该方法。

Ad 2. A direct reference to a mounted component (as your thisManager does) has some additional risks. 广告2。直接引用已安装的组件(如thisManager所做的)还有一些其他风险。 React's designs and limitations are there for a reason: to maintain unidirectional flow and component hierarchy with props and state, to make things easy to maintain. 存在React的设计和局限性是有原因的:使用道具和状态维护单向流和组件层次,使事情易于维护。

If you break this pattern - by building a backdoor into a component, which allows manipulation of state - you break this design principle of react. 如果您打破这种模式-通过在组件中构建后门,从而允许对状态进行操作-就会打破反应的设计原则。 It is a quick shortcut, but is sure to cause great pain and frustation when your app grows. 这是一个快速的捷径,但是一定会在您的应用增长时引起极大的痛苦和沮丧。

As far as I know, the only acceptable exceptions to this rule are: 据我所知,该规则唯一可接受的例外是:

  • Methods inside a component that respond to ajax call results, to update state (eg after fetching data from server) 组件内部响应Ajax调用结果的方法以更新状态(例如,从服务器获取数据后)
  • Methods inside a component to handle triggers from its direct descendent children components (eg run validation on form after a child button has been clicked) 组件内部的方法,用于处理其直接后代子组件的触发器(例如,在单击子按钮之后在窗体上运行验证)

So if you want to use it for that purpose, then you should be fine. 因此,如果您想将其用于此目的,那应该没问题。 Word of warning: the standard react approach guards random access to components , because the invoking component or method needs to have a reference to the component. 警告词: 标准的react方法会保护对组件的随机访问 ,因为调用的组件或方法需要引用该组件。 In both examples such a reference is available. 在这两个示例中,都有这样的参考。
In your setup, ANY outside piece of code could lookup the ref to the "header" in your table, and call the method which updates state. 在您的设置中,任何外部代码段都可以在表中的“ header”中查找引用,并调用更新状态的方法。 With such indirect reference, and no way of telling which source actually called your component, your code is likely to become much harder to debug/ maintain. 有了这样的间接引用,并且无法分辨哪个源实际上调用了您的组件,因此代码的调试/维护可能会变得更加困难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM