反应通量存储发出更改不会在两个组件中触发

React Flux Store emitChange Not Firing in Both Components

本文关键字:两个 组件 存储      更新时间:2023-09-26

我有两个不同的组件,它们利用相同的AuthStoreFacebookUserQuiz

FacebookUser组件通过执行login操作来更新AuthStore,该操作会导致它执行emitChange。但是,QuizonChange处理程序不会触发。

身份验证存储.js

console.log("AuthStore::CREATED");
var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var AuthConstants = require('../constants/AuthConstants');
var assign = require('object-assign');
var CHANGE_EVENT = 'change';
var _user = undefined;
var AuthStore = assign({}, EventEmitter.prototype, {
  isLoggedIn: function() {
    return _user !== undefined;
  },
  getUser: function() {
    return _user;
  },
  emitChange: function() {
    console.log('AuthStore::emitChange');
    this.emit(CHANGE_EVENT);
  },
  addChangeListener: function(callback) {
    console.log('AuthStore::addChangeListener', callback);
    this.on(CHANGE_EVENT, callback);
  },
  removeChangeListener: function(callback) {
    this.removeListener(CHANGE_EVENT, callback);
  }
});
// Register callback to handle all updates
AuthStore.dispatchToken = AppDispatcher.register(function(action) {
  console.log('AuthStore::action', action);
  switch(action.actionType) {
    case AuthConstants.AUTH_LOGIN:
      _user = action.user;
      AuthStore.emitChange();
      break;
    case AuthConstants.AUTH_LOGOUT:
      _user = undefined;
      AuthStore.emitChange();
      break;
    default:
      // no op
  }
});
module.exports = AuthStore;

FacebookUser.jsx

var AuthActions = require('../../actions/AuthActions');
var AuthStore = require('../../stores/AuthStore');
function componentWillMount() {
  AuthStore.addChangeListener(this.onChange);
}
function onChange() {
  console.log('FacebookUser::onChange');
  var user = AuthStore.getUser();
  this.setState(user);
}
function populateUserProfile(userId) {
  FB.api('/' + userId, {fields: 'email,name'}, function(response) {
    console.log('FacebookUser::populateUserProfile', response);
    AuthActions.login(response);
  }.bind(this));
}

测验.jsx

var AuthStore = require('../../stores/AuthStore');
var QuizStore = require('../../stores/QuizStore');
function componentWillMount() {
  AuthStore.addChangeListener(this.onChange);
  QuizStore.addChangeListener(this.onChange);
}
function onChange() {
  console.log('Quiz::onChange');
  var quiz = QuizStore.getQuiz();
  if (!quiz.person.email) {
    var user = AuthStore.getUser();
    quiz.person.email = user.email;
  }
  this.setState(quiz);
}

应用调度程序.js

var Dispatcher = require('flux').Dispatcher;
module.exports = new Dispatcher();

我以为这些商店是辛格尔顿的,但是,情况似乎并非如此。我知道我错过了一些愚蠢的东西。期待答案!

控制台输出

下面你可以看到FacebookUser::onChange着火了。我很确定问题是为这两个组件创建了AuthStore。从AuthStore::CREATED日志中可以非常明显地看到这一点。

AuthStore::CREATED
QuizStore::create
AuthStore::addChangeListener onChange() {
  console.log('Quiz::onChange');
  var quiz = QuizStore.getQuiz();
  if (!quiz.person.email) {
    var user = AuthStore.getUser();
    quiz.person.email = user.email;
  }
  th…
QuizStore::addChangeListener onChange() {
  console.log('Quiz::onChange');
  var quiz = QuizStore.getQuiz();
  if (!quiz.person.email) {
    var user = AuthStore.getUser();
    quiz.person.email = user.email;
  }
  th…
AuthStore::CREATED
AuthStore::addChangeListener onChange() {
  console.log('FacebookUser::onChange');
  var user = AuthStore.getUser();
  this.setState(user);
}
FacebookUser::statusChangeCallback Object {authResponse: Object, status: "connected"}
FacebookUser::populateUserProfile Object {email: "mperren@gmail.com", name: "Michael Perrenoud", id: "10209047315608853"}
AuthActions::login
AuthStore::action Object {actionType: "AUTH_LOGIN", user: Object}
AuthStore::emitChange
FacebookUser::onChange

而不是公开构造函数,在您的商店中公开一个实例调用new并公开该实例。这样,它将是一个单一实例,在测试中,我公开了一个非默认导出,以便我可以为每个测试重新初始化一个存储。

所以这个问题最终有点深奥。我用不同的ReactDOM渲染器包含这个用户组件。有效地喜欢它自己的应用程序。这就是导致问题的原因。因为它们处于不同的范围内,所以它们不共享相同的商店。将组件移动到由应用程序的根组件呈现可以修复它。