Server rendering

I tried to figure out how to visualize the reaction on the server (node ​​/ express) and finally found a simple enough tutorial to understand what was going on. But now, after setting everything up, I get an error message in the React.render method:

here is my component file:

 var React = require('react'); var box = React.createClass({ render: function() { return ( <div style='padding: 10px'> this.props.text </div> ); } }); React.render(<box text='testing server side'/>, document.body); module.exports = box; 

I get an error when starting npm start :

document not defined

how do i get around this? Do I need or don't need a rendering method?

in order to provide more context, this box component is required by another component:

 var React = require('react'); var Box = require('../react-jsx/box.js'); //this is the box component var Component = React.createClass({ render: function() { return ( <html> <head> <title> React Server Rendering </title> </head> <body> <Box text='testing'/> <script src="public/bundle.js"></script> </body> </html> ); } }); module.exports = Component; 

and all this is used in index.js

 require('node-jsx').install(); var React = require('react'); var Component = require('../custom-modules/test-react-server-module.js'); var express = require('express'); var router = express.Router(); router.get('/react', function(req, res, next) { var markup = React.renderToString(Component()); res.send(markup); }); module.exports = router; 

and if I remove the rendering method, I get this error in the browser:

Unable to read property '__reactAutoBindMap' from undefined

I saw some people say that it may be due to the jsx transformer being old, but I think I have the latest version

I have no ideas

+6
source share
3 answers

First of all, I recommend updating the version of React. The current version provides two different top-level APIs: React , which is usually used to create components, and ReactDOM , which provides DOM methods that will be used at the top level of your application.

Here you can specify:

  • You are trying to run code that should only be executed in a browser. NodeJS No Document . I would suggest using webpack to pack these component files and serve them in a browser.

  • For an isomorphic React application, you need to have a client.js file that calls the rendering function for the same component that you are trying to do inside index.js . Got it?

Understand ReactDOM.render as indicated in the documentation:

Edit the ReactElement element in the DOM in the supplied container and return a reference to the component (or returns null for idle components).

If the ReactElement was previously mapped to the container, this will perform the update and only mutate the DOM as necessary reflect the last React component.

Keep in mind that ReactDOM.render should be used only a few times and usually at the top level of your application, only once.

Having said that, your box.js should look like this:

 var React = require('react'); var box = React.createClass({ render: function() { return ( <div style='padding: 10px'> this.props.text </div> ); } }); module.exports = box; 

For proper operation, you will need to create the main component main-component-file.js :

 var React = require('react'); var Box = require('../react-jsx/box.js'); //this is the box component var Component = React.createClass({ render: function() { return ( <html> <head> <title> React Server Rendering </title> </head> <body> <Box text='testing'/> <script src="public/bundle.js"></script> </body> </html> ); } }); module.exports = Component; 

Inside bundle.js you need to make sure that it is invoked so that the main component tries to re-render:

 var React = require('react'); var ReactDOM = require('react-dom'); var Component = require('main-component-file.js'); ReactDOM.render(<Component/>, document.body); 

Last but not least: index.js , the server file. Change React.renderToString to ReactDOMServer.renderToString , create a React element from the main component and use it:

 var element = React.createElement(Component) router.get('/react', function(req, res, next) { var markup = ReactDOMServer.renderToString(element); res.send(markup); }); 

Remember to include the npm react-dom/server package in your index.js .

Links used in the article:

+10
source

You have to delete this

 React.render(<box text='testing server side'/>, document.body); 

No need for this. What you essentially say in order to React is to do it right then and there.

document.body does not exist yet because you are executing it on the server side, and you also do not need it because you are passing the component to the renderToString function on request in the router . (I also think @PeterLyons is correct, so take a look at his answer too).

Also, if you are strictly using React for viewing only, you can take a look at express-react-views . They have a good guide on using React with Express, and you can essentially use it only for server-side rendering. I don't think this is ideal for using react-router depending on what you are building, but it illustrates how React handles server-side rendering and works with Express.

+1
source

In a server environment, you need to use react-dom/server package renderToString . This will return the HTML as a string that you can send in your express response.

0
source

All Articles