Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server rendering with same data is generating different checksums and ids #3

Closed
jeffbski opened this issue Mar 2, 2015 · 5 comments

Comments

@jeffbski
Copy link

jeffbski commented Mar 2, 2015

Jess,

If you modify your server/index.js so that it is actually rendering with the latest data on every request (rather than always using the same copy of html),

then even though the data is still the same, the checksum rendered is now different on every render???

app.get('/', function(req, res) {
  res.send(layoutTemplate({
    content: React.renderToString(
      TodoItemFactory({done: false, name: 'Write Tutorial'}))
  }));
});

In fact, I found that simplifying the render down to just

React.renderToString(React.createElement('div')); 

generates a different checksum and id each time it is called?

Something doesn't add up here.

Thoughts?

Thanks,

Jeff

@jeffbski
Copy link
Author

jeffbski commented Mar 2, 2015

I think I figured out the issue. For server side rendering it will use random root id's and since the checksum uses that it won't match. However there is some other algorithm on the client that can determine if things are different (other than simply comparing checksum).

If things aren't matching one should see a warning in the console log "React attempted to reuse markup in a container but the checksum was invalid." so if we aren't seeing that then React is properly using the content.

@jesstelford
Copy link
Owner

Hey Jeff, you're correct: that is expected behaviour. The important part is that the data is the same. I believe react takes the instance into account when calculating the checksum for rendering to string, but as you say, it does not use it when rendering in the browser.

To show that React is still correctly recognizing the element on the browser, you can change the browser-side data to be different, then use the "Timeline" tab in Chrome to look for repaints:

With same data server & browser side
same data

With different data server & browser side
different data

You can see the extra paint and composite steps are performed when the data is different.

@jeffbski
Copy link
Author

jeffbski commented Mar 3, 2015

Thanks @jesstelford for pointing out how to see the render in chrome debugger, that helps.

@jesstelford
Copy link
Owner

You're welcome :)

I used a little trick to isolate the browser-side changes: I wrapped the React.render() call in a 1000ms setTimeout, which allowed me to hone in on just the section I was interested in.

Don't forget to check out Part 2: Unit testing React Components with Mocha + jsdom

@jeffbski
Copy link
Author

jeffbski commented Mar 3, 2015

Thanks, yes I have already went through part 2 and 3 :-)

I liked your idea of using jsdom to test with Mocha rather than trying to fire up something like Phantom. The article helped me get all that working, though I did have to make a few changes to use with the latest jsdom. I'll open a PR with the changes I needed to make.

I appreciated you sharing all of this since it made it easier to get going.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants