Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stable reactid for server-side rendering

When using React to render components on the server, I notice that the data-reactid attributes are effectively random. I understand that's expected. (https://groups.google.com/forum/#!topic/reactjs/ewTN-WOP1w8)

However it's a little surprising that this otherwise functional framework introduces such non-determinism in the view output. It means that successive renderings of a view with identical state will create different HTML, preventing, for instance, the view engine from returning a '304 Not Modified' or generating a reliable ETag. (I appreciate such caching could be handled at a higher infrastructure layer as well.)

Is there a way to seed the generation of the identifier so that the reactids are deterministic? Or is the reason that's a bad idea explained somewhere else?

like image 534
Sebastian Good Avatar asked Feb 15 '15 02:02

Sebastian Good


2 Answers

In the final comment on the Google Group thread Ben Alpert says:

For server rendering, it's important that different rendered components don't have colliding IDs (even if they're rendered on different servers, for instance) so we pick them at random.

like image 185
Brett DeWoody Avatar answered Nov 01 '22 01:11

Brett DeWoody


Also recently thought about it(just started to use reactjs),

Possible solution is quite simple - there is no requirement for ETag to be generated from real html... - it can be generated from displayed data.

So you can generate it from virtual dom - just use React.renderComponentToStaticMarkup(…) and generate ETag from it...

Or you can remove all reactid's from rendered html with regexp before hashing it(likely faster then separate render)...

In case if you are using express, this would be something like:

var virtualDom = React.createFactory(Handler)({});
var html = React.renderToString(virtualDom);

var etag = app.get('etag fn');
if (etag) {
  etag = etag(React.renderComponentToStaticMarkup(virtualDom), 'utf8');
  etag && res.set('ETag', etag);
}

res.render( ... );
like image 35
Bogdan Savluk Avatar answered Nov 01 '22 01:11

Bogdan Savluk