Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/444.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 父组件上的ReactJS事件驱动更新_Javascript_Publish Subscribe_Reactjs - Fatal编程技术网

Javascript 父组件上的ReactJS事件驱动更新

Javascript 父组件上的ReactJS事件驱动更新,javascript,publish-subscribe,reactjs,Javascript,Publish Subscribe,Reactjs,我有一些部件深深地埋在他们父母的心里。我有一个用户变量,它是在这个链的绝对顶端获取的一个ProfilePage组件,并通过props一路向下传递。但是,有时用户会在页面上的一个小组件(例如AboutMe组件)中更新其配置文件。我当前的流程是让AboutMe组件通过ajax更新用户,然后在我的pubsub上触发一个名为“profileupdate”的事件。触发“profileupdate”时,ProfilePage会通过ajax再次获取用户,因此所有道具都会更新。这一策略似乎奏效,但它几乎总能带来

我有一些部件深深地埋在他们父母的心里。我有一个用户变量,它是在这个链的绝对顶端获取的一个ProfilePage组件,并通过props一路向下传递。但是,有时用户会在页面上的一个小组件(例如AboutMe组件)中更新其配置文件。我当前的流程是让AboutMe组件通过ajax更新用户,然后在我的pubsub上触发一个名为“profileupdate”的事件。触发“profileupdate”时,ProfilePage会通过ajax再次获取用户,因此所有道具都会更新。这一策略似乎奏效,但它几乎总能带来:

Uncaught Error: Invariant Violation: replaceState(...): Can only update a mounted or mounting component.
我知道这个错误是由于ProfilePage没有被装载并替换了它的用户状态

下面是一个我这样做的地方的例子:

在ProfilePage组件中:

var ProfilePage = React.createClass({
  getInitialState: function() {
    return {};
  },

  updateUser: function() {
    this.setUser('/api/users/' + this.props.params.userId);
  },

  setCurrentUser: function(currentUser) {
    this.setState({ currentUser: currentUser });
  },

  resetCurrentUser: function() {
    auth.getCurrentUser.call(this, this.setCurrentUser);
  },

  componentWillReceiveProps: function(newProps) {
    this.setUser('/api/users/' + newProps.params.userId);
  },

  componentDidMount: function() {
    PubSub.subscribe('profileupdate', this.updateUser);
    PubSub.subscribe('profileupdate', this.resetCurrentUser);
    this.resetCurrentUser();
    this.updateUser();
  },

  setUser: function(url) {
    $.ajax({
      url: url,
      success: function(user) {
        if (this.isMounted()) {
          this.setState({ user: user });
        } else {
          console.log("ProfilePage not mounted.");
        }  
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.userId, status, err.toString());
      }.bind(this)
    });
  },
然后,在AboutInput组件中: 档案页面->档案盒->关于->关于输入

updateAbout: function(text) {
  var url = '/api/users/' + this.props.user._id;
  var user = this.props.user;
  user.about = text;
  $.ajax({
    url: url,
    type: 'PUT',
    data: user,
    success: function(user) {
      auth.storeCurrentUser(user, function(user) {
        return user;
      });
      PubSub.publish('profileupdate');
      this.propagateReset();
    }.bind(this),
    error: function(xhr, status, err) {
      console.error(status, err.toString());
      this.propagateReset();
    }.bind(this)
  });
},
这里的要点是ProfilePage在触发profileupdate事件时再次获取用户


我在这里使用了错误的策略吗?我如何处理这种更新?我可以强制安装Profile页面吗?那真是太理想了。此外,有趣的是,无论控制台是否记录ProfilePage已卸载,用户仍会更新。

我真的想看看Facebook的FLUX实现。它将大大简化您的工作流程。我猜这在目前不是一个选项,但请确保您的组件在删除它们时取消订阅。例如:

componentWillUnmount: function () {
    var self = this;
    self.store.removeListener('change', self._setState);
    self._setState = null;
}
或者在您的情况下,在替换组件时,使用上述方法从PubSub实现中取消订阅。因此,正在对已卸载的React组件调用“profileupdate”。差不多

componentWillUnmount: function () {
    PubSub.unsubscribe('profileupdate', this.updateUser);
    PubSub.unsubscribe('profileupdate', this.resetCurrentUser);
    this.updateUser = null;
    this.resetCurrentUser = null;
}

这正是错误的状态。您试图在不再装载或已删除的React组件上设置状态。

请提供一个导致不变冲突的代码示例。嗯,我来看看flux实现。这个解决方案不意味着道具不会更新吗?ProfilePage将在何时重新装载和更新?这应该在所有绑定了事件的组件上进行。您应该始终将事件解除绑定到将要装载和卸载的任何组件。否则,您将遇到内存泄漏,并会发生各种奇怪的错误。在上面的代码片段中,您没有显示如何实现ProfileBox->About->AboutInput。例如,您是否正在传递道具或状态,以及这些组件是如何更新的?用户是ProfilePage检索到的状态。该用户作为道具通过多个组件层传递,最终到达AboutInput。因此,如果我取消订阅ProfilePage中的事件,那么AboutInput会触发该事件,然后ProfilePage会重新装载并重新订阅该事件,这是否意味着它仍将更新?