Reactjs 组件之间的通信

IT技术 javascript reactjs
2021-04-08 21:13:47

在使用 Redux、flux 和其他发布/订阅方法苦苦挣扎之后,我最终采用了以下技术。我不知道这是否会造成一些大的损害或缺陷,所以把它贴在这里是为了让有经验的程序员了解它的优缺点。

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 作为数据发送,它完美地呈现了所需的组件,我可以在没有任何发布/订阅或深入传递props的情况下调用渲染来调用具有更改 this.setState 的父方法以导致重新渲染.

到目前为止,该应用程序运行良好,我也很喜欢它的简单性。请阐明这种技术的优缺点

问候

编辑:

调用 render 很糟糕,所以我将其更改为另一种方法以获得此设置的更多优缺点。

1个回答

这个设置有两个主要问题:
1. 你不应该直接调用 react 生命周期方法
2. 组件的后门是一个坏主意,这会破坏 react 的可维护性

广告 1: 如果render()直接调用(或任何其他 react 方法),react 可能不会调用componentDidMount()组件树中的 、componentDidUpdate()` 等生命周期方法。

危险是:

  • 有许多设计react成分在很大程度上依赖于生命周期方法被解雇:getInitialState()componentWillReceiveProps()shouldComponentUpdate()componentDidMount(),等等等等,如果你打电话render()直接,许多组件可能会破坏或显示奇怪的行为。
  • 你冒着破坏 React 差异引擎的风险:通过生命周期管理,React 在它的(内部)内存中保留了一个 DOM 的虚拟副本。要正常工作,此副本的完整性对于 react 的工作至关重要。

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

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

广告 2. 直接引用已安装的组件(如您的 thisManager 所做的)具有一些额外的风险。React 的设计和限制是有原因的:使用 props 和 state 维护单向流和组件层次结构,使事情易于维护。

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

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

  • 响应 ajax 调用结果的组件内部方法,以更新状态(例如,从服务器获取数据后)
  • 组件内部处理来自其直接后代子组件的触发器的方法(例如,在单击子按钮后在表单上运行验证)

因此,如果您想将其用于该目的,那么您应该没问题。警告:标准的 react 方法会保护对组件的随机访问,因为调用组件或方法需要引用该组件。在这两个示例中,都提供了这样的参考。
在您的设置中,任何外部代码都可以查找表中“标题”的引用,并调用更新状态的方法。有了这样的间接引用,并且无法知道哪个源实际调用了您的组件,您的代码可能会变得更难调试/维护。

好的,谢谢,我编辑了这个问题,现在想知道为什么会中断,因为基本上我想要的是用新数据重新渲染组件,所以最后一件事是订阅某个事件并执行它,因为我发现简单的是而不是发布事件我将数据直接发送到我可以执行 this.setState 的函数?你说什么?
2021-05-31 21:13:47
请参阅我的回答中的广告 2:我仍然建议不要使用任何间接后门进入组件:最好坚持标准反应:将道具从父组件发送到组件,从组件内部启动侦听器。
2021-06-01 21:13:47
谢谢@wintvelt,那么任何其他可能导致 this.setState 的方法都可以吗?
2021-06-21 21:13:47