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