1

We're building a rather complex React + Reflux application and have a couple of stores that listen to some actions originating from some other component. Eg:

var FooStore = Reflux.createStore({

  listenables: [FooActions, BarActions],

  ...
});

I don't find this approach ideal for a couple of reasons:

  • When extending the BarActions you can unknowingly introduce an action with the same name as a Foo action, which will result in a regression bug
  • It's not necessarily obvious which functions relate to the BarActions when reading the code in the FooStore
  • If you are aware of a naming conflict, then you need to create overly verbose actions

How can I avoid these issues?

EDIT

My current approach to avoid these issues is to specifically state which actions the store is listening to over and above its main source of events:

var FooStore = Reflux.createStore({

  listenables: [FooActions],

  init: function() {
    this.listenTo(BarActions.shoot, this.onShoot);
  },

  ...
});
Markus Coetzee
  • 3,384
  • 1
  • 29
  • 26
  • The only really good solutions here involve changes to reflux (dynamically generating action names). Morhaus's solution is reasonable, though. – Brigand Apr 21 '15 at 16:07
  • This is the reason why people suggest that using only one action creator is preferred. However, we also have quite a complex application and I prefer multiple action creators too. Until now, we have been making the action names unique by manually putting part of the name of the action creator in the name of the action itself. I do prefer a change to Reflux or in the meanwhile something like @Morhaus's solution. – Björn Boxstart Apr 24 '15 at 12:19

1 Answers1

2

Since FooActions and BarActions are simple key-value stores, where the key is the name of an action and value is the action itself, you could merge them into a new object and automatically prefix their keys to avoid conflicts with a rather simple function:

function mix(actionMaps) {
  var prefixedActionMap = {};
  Object.keys(actionMaps).forEach(function(mapKey) {
    var actionMap = actionMaps[mapKey];
    Object.keys(actionMap).forEach(function(actionKey) {
      // shoot -> fooShoot
      var prefixedActionKey = mapKey + actionKey.charAt(0).toUpperCase() + actionKey.slice(1);
      prefixedActionMap[prefixedActionKey] = actionMap[actionKey];
    });
  });
  return prefixedActionMap;
}

Your FooStore would then look like:

var FooStore = Reflux.createStore({

  listenables: [mix({ foo: FooActions, bar: BarActions })],

  onFooShoot: function() { ... },

  onBarShoot: function() { ... },

});
Alexandre Kirszenberg
  • 35,938
  • 10
  • 88
  • 72