If you are using a Flux-style architecture, this can be achieved nicely with a Store.
Imagine you have a store called MyModalStore (or ShareModalStore, or whatever the modal is). The store contains all the data needed for the modal content, as well as whether or not it should be displayed.
Here is a simplified store that keeps track of whether the modal is visible, and what the title is:
MyModalStore.js
var _visible = false;
var _modalTitle;
var MyModalStore = {
isModalVisible: function() {
return _visible;
},
getModalTitle: function() {
return _modalTitle;
}
};
MyModalStore.dispatchToken = Dispatcher.register(function(payload) {
var action = payload.action;
switch (action.type) {
case 'SHOW_MODAL':
_visible = true;
_modalTitle = action.modalTitle;
MyModalStore.emitChange();
break;
case 'HIDE_MODAL':
_visible = false;
MyModalStore.emitChange();
break;
}
});
module.exports = MyModalStore;
Then the components that want to show the modal fire a 'SHOW_MODAL' action with a modalTitle, and the modal component itself listens for store changes to know when to show itself.
You can see this flux pattern in example projects on facebook/flux on github.
Without using flux, I guess you would provide a callback down your module hierarchy so that anyone can hit the callback to show the modal, and that is delegated to the actual modal component at the top-level. This isn't a great approach for larger applications, so I'd recommend the flux approach.
We published some store helper code here, but there are a lot of other libraries and examples out there as well.