Calling React View from Express
2021 edit:
the modern solution is to use the create-react-app tool, followed by dropping in your code where needed. It's been set up to do the rest for you. The React landscape has changed a fair bit over the last six years.
original 2015 answer:
The usual thing is to use react-router to take care of the routes; write your React app as a single React app (i.e. all your JSX source ends up bundled into a single app.js file, which knows how to load all your "pages" or "views") and then use express (or Hapi, or any other server process) mostly as your API and asset server, not your page/view generator.
You can then tap into the routes you set up in the react-router
Router object so that on the express side you can forward your users to the URL that react-router
can deal with for content loading, so you get
- user request site.com/lol/monkeys
- express redirects to /#/lol/monkeys
- your react app loads the correct view because of the routes in Router
- optionally, your app does a history.replaceState so that the user sees site.com/lol/monkeys (there are some react-router tricks to do this for you)
You can also automate most of this through server-side-rendering but the name can be confusing: you still write your React app as if there is no server involved at all, and then rely on React's render mechanism to fully render individual "pages" for a requested URL which will show all the right initial content while also then loading your app and silently hooking it back into the content the user is looking at, so that any interactions past the initial page load are handled by React again, and subsequent navigation is "fake" navigation (your url bar will show a new URL but no actual network navigation will happen, React simply swaps content in/out).
A good example for this is https://github.com/mhart/react-server-example
The other answers work with the usual way to use react, to replace an element in the dom like so
React.render(<APP />, document);
but if you want react to be your "template language" in express, you can also use react to render a simple string of html like so
app.get('/', function(req, res) {
var markup = React.renderToString(<APP />); // <-- render the APP here
res.send(markup); // <-- response with the component
});
there are a few other things you need to take care of in terms of bundling all the dependencies and working with jsx. this simple minimalist tutorial and this blog post helped me understand the situation better
note that the sample code in the tutorial uses this syntax
var markup = React.renderToString(APP());
which has been deprecated and will cause an error. to use it you'd have to replace
var APP = require('./app');
with
var APP = React.createFactory(require('./app'));
or just render jsx like i did in the first example. to get the tutorial to work i might have also had to use more recent versions of the dependencies in package.json.
once you've got that down a fancier tutorial shows a more powerful way to use react-engine to render react within express
Instead of manually dealing with React.render you can use a library called react-helper (https://github.com/tswayne/react-helper). It sets up a div for you, binds your react components to the div, allows you to pass properties to your components server side, and can even handle server-side rendering if you have webpack configured for your node app or are willing to use babel-register (not recommended for prod).
If you want to keep it simple you can do this for the entry point of your app:
routes | index.js
app.get('/', function(request, response){
// how do we call the route that will run index.html ?
res.sendfile('../views/index.html');
});
React is going to target a specific element on your index.html page in it's render method:
React.render(<Application />, document.getElementById('foo'));
So if your javascript is included in index.html and an element with that id is present react is going to inject your Application into that div. From that point onwards you can do all of the routing with react-router OR you can setup different routes in express and handle them like you did index.html