Yes, yes, yes. At my company we've been switching everything over to React for both client/server rendering using our own ExecJS rendering engine for Ruby on Rails. It certainly adds a bunch of complexity to the stack, but every improvement we make provides new benefits in terms of the ease with which we can keep the API stack we like while cranking out rich UI while worrying much less about the client/server distinction.
Needless to say, I am a React fan.
That said, here are some things you will run into as you build more complex applications with this architecture. Some are related to shared browser/server JavaScript and some are React in general:
* You will find that some JavaScript libraries you want to use should not be loaded into the server context.
* On occasion, you will need to add server-vs-browser conditionals. And creating components to deal with browser-focused JS libraries (think Google Maps) will require some liberal and sometimes awkward use of React component lifecycle methods.
* Until there's a nice, agreed-upon open-source layering library for React out there, or you make your own, things like click-based (not hover-based, which can work with just CSS) dropdowns and non-modal dialogs are weirder to get to dismiss (when clicking outside of them) than they should be. Just because of the way React events happen and are bound.
* Also because of the way events are bound, it's awkward to write nice reusable form components. Without some trickery, you can only bind events from the component you're writing to its descendents. You can't bind events from one descendent to another. You end up writing a new component for each form every time, which isn't necessarily terrible until you want to make a fancy form builder like Rails provides in ERB. I've tried every which way around this, and I've had some success, but the solution always feels wrong and ugly no matter how I do it.
* This is really more of a good thing, but it's so enabling that you'll never really be done adding convenience features. There are just so many "Wouldn't it be nice if ____ just worked?" scenarios that get you thinking about the next reusable tool you want. I spend a LOT of time trying to create the "perfect" browser-side data store abstraction and the "perfect" lazy loader/renderer component for not-yet-fetched models.
The tradeoffs thus far have been worth it, but we haven't yet found or built the holy grail. So many things are so much easier than the old ways, but sometimes they're harder.