This is exactly the problem we've been running into building a medium sized interactive app in React. The management of data flow and state changes through the component hierarchy with callbacks can get quite complex, and you end up writing lots of callback boilerplate. So we've ended up rolling an event system that sits alongside the React components, and a lot of our app's interactivity is managed through the event system.
We're still learning, and are still not sure if we'll be using React for our production version of what's now a prototype. But I'm starting to feel more and more that we should use the strong points of React (the virtual DOM; so, send big CSS or DOM changes to the virtual DOM via state changes), and discard the other stuff (synthetic events, wiring components together via callbacks). It's tricky figuring out the best way to use it.
I'm starting to think that I would rather just have React as an "immediate mode rendering engine" -- a thin view library. In its entirety it feels too constraining.
This is exactly how react was intended to be used, and our larger apps use the flux system architecture which closely resembles what you've described. There's an example in the react repo. Om takes a different (but equally viable) approach.
We're still learning, and are still not sure if we'll be using React for our production version of what's now a prototype. But I'm starting to feel more and more that we should use the strong points of React (the virtual DOM; so, send big CSS or DOM changes to the virtual DOM via state changes), and discard the other stuff (synthetic events, wiring components together via callbacks). It's tricky figuring out the best way to use it.
I'm starting to think that I would rather just have React as an "immediate mode rendering engine" -- a thin view library. In its entirety it feels too constraining.