【问题标题】:Communication between Reactjs ComponentsReactjs 组件之间的通信
【发布时间】:2016-06-09 13:05:46
【问题描述】:

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

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 或深度传递道具的情况下调用渲染来调用父方法,并更改 this.setState 以导致重新渲染。

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

问候

编辑:

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

【问题讨论】:

  • 虽然这适用于非常有限的用例,如您提供的示例,但它会干扰反应组件的生命周期。 render 方法永远不会被直接调用,也不应该有输入,这使得它不纯。至少,公开一个不同的公共方法,它接受你发送来渲染的任何东西。在该方法中执行 setState ,它将隐式调用渲染。最后而不是渲染调用该方法。
  • 谢谢@HazardouS,当然是对的,但是技术呢,基本上我没有公开它是可以调用渲染的参考,我猜 setState 会做同样的效果加上破坏性部分将数据作为参数发送到渲染函数?
  • SO 应用程序不太适合长解释 :)。请阅读 React 中的纯渲染方法假设。还有 React 批量渲染,这就是为什么不应该直接调用它的原因。

标签: javascript reactjs


【解决方案1】:

此设置的两个主要问题:
1.永远不要直接调用 react 生命周期方法
2.组件后门是个坏主意,它破坏了 React 的可维护性

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

危险是:

  • 许多带有 React 组件的设计严重依赖于被触发的生命周期方法:getInitialState()componentWillReceiveProps()shouldComponentUpdate()componentDidMount() 等。如果你直接调用render(),许多组件可能会损坏或表现出奇怪的行为。
  • 您冒着破坏 react 差异引擎的风险:通过生命周期管理,react 在其(内部)内存中保留了 DOM 的虚拟副本。为了正常工作,这个副本的完整性对于反应的工作至关重要。

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

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

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

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

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

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

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

【讨论】:

  • 感谢@wintvelt,所以任何其他可能导致 this.setState 的方法都可以吗?
  • 对,谢谢,我编辑了这个问题,现在想知道为什么会中断,因为本质上我想要的是用新数据重新渲染组件,所以最后一件事是订阅一些事件并执行它,在哪里因为我发现很容易而不是发布一个事件,我将数据直接发送到我可以执行 this.setState 的函数?你说什么?
  • 在我的回答中查看广告 2:我仍然建议不要对组件进行任何间接后门:最好坚持标准反应:将 props 从父组件发送到组件,从组件内部启动侦听器。
猜你喜欢
  • 1970-01-01
  • 2016-08-10
  • 2015-06-29
  • 2014-12-21
  • 2019-05-30
  • 2015-09-18
  • 2016-05-01
  • 2017-09-04
  • 2021-03-02
相关资源
最近更新 更多