Material-ui: Can't render a consistent classname on server and client [v1]

Created on 19 Aug 2017  路  18Comments  路  Source: mui-org/material-ui

Problem description

While using the server side rendering, the client side and server side did not product consistent class names, this problem happened on MuiTypography-root, iGrid-typeContainer, MuiButton-root, MuiList-root. I'm not sure it's a bug or I misconfigured the material-ui...

Steps to reproduce

Here are the codes:

import React from 'react'

import Paper from 'material-ui/Paper'
import Grid from 'material-ui/Grid'

import MemberListUnit from './MemberListUnit'

import ssr from '../../modules/ssrComponent'

import './stylesheets/MemberList.less'

class MemberList extends React.Component{
  componentDidMount() {
    this.props.switchBackground('Team member', require('./images/background.jpg'));
  }

  constructMemberUnit(group) {
    return this.props.pageData[group].map(member => (
        <MemberListUnit key={member.__fileName}
                        faceImage={member.image} name={member.name}
                        title={member.title} researchDirection={member.researchDirection} />
      ))
  }

  render(){
    return (
      <Paper elevation={4} className="content_wrap member_list_wrap">
        <section>
          <h2 className="member_list_title">PI Members</h2>
          <Grid container className="member_list">
            {this.constructMemberUnit('T')}
          </Grid>
        </section>
      </Paper>
    )
  }
}

export default ssr(MemberList, '/api/member/list')

The console reported:

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
 (client) -46 MuiButton-root-148" type="button" ro
 (server) -46 MuiButton-root-193" type="button" ro

Likewise, another page reported the following error:

 (client) class="MuiList-root-65 MuiList-padding-6
 (server) class="MuiList-root-174 MuiList-padding-

Versions

  • Material-UI: v1.0.0-beta.5
  • React: 15.6.1
  • Browser: Edge 40.15063.0.0, Firefox 55.0.1, Vivaldi 1.11.917.39

Most helpful comment

@rangeoshun Your server is using NODE_ENV=production while your client is using NODE_ENV=development.

All 18 comments

The documentation web site is now service side rendered #7759. It's most likely a misconfiguration, I have been using SSR with next.js in production with no issue.

@Losses have u solved your issue as I have the same?

Do you have a reproduction test case?

Seems like I'm idiot ;-) Have purely read ssr doc page. Sorry

Let us know if you find something we could be improving.

@isnifer Yes, solved. The problem happened because I didn't completely upgrade my code from material-ui alpha to beta. Check if you add sheetsManager prop to MuiThemeProvider on the server side.

Hi there! Dunno if I should open a ticket for this, or I'm the one messing up, but seems I have this issue, at least similar.

I use MeteorJS as stack, and switched to React + MaterialUI instead of Blaze. I have a little test repo, in which I want to POC the SSR approach. I managed to get it working, but I have this Warning in console:

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
 (client) tid="3"><div class="MuiGrid-typeContaine
 (server) tid="3"><div class="typeContainer-0-0 sp

In my case the class names differ more than in the case of the previous reporters. Although I think I'm following the guide as I should, with a few tweeks because of Meteor. Here are the two compiled HTMLs.

The server side:

<div data-reactid="3">
  <div class="typeContainer-0-0 spacing-xs-24-0-16" data-reactid="4">
    <div class="typeItem-0-1 grid-xs-12-0-30 grid-sm-6-0-37 grid-lg-4-0-61 container" data-reactid="5">
      <div class="root-0-83 shadow2-0-87 rounded-0-84" data-reactid="6">
        <header data-reactid="7">
          <h1 data-reactid="8">Todo List</h1>
          <form data-reactid="9">
            <div class="root-0-110" style="width:100%" data-reactid="10">
              <label class="root-0-120 root-0-114 formControl-0-115 animated-0-118" data-reactid="11">
                <!-- react-text: 12 -->Type to add new tasks
                <!-- /react-text -->
              </label>
              <div class="root-0-124 formControl-0-125 inkbar-0-126 underline-0-132" data-reactid="13">
                <input type="text" class="input-0-128 inputSingleline-0-135" value="" name="text" data-reactid="14">
              </div>
            </div>
          </form>
        </header>
        <!-- react-empty: 15 -->
      </div>
    </div>
  </div>
</div>

And on the client:

<div data-reactid="3">
  <div class="MuiGrid-typeContainer-1 MuiGrid-spacing-xs-24-17" data-reactid="4">
    <div class="MuiGrid-typeItem-2 MuiGrid-grid-xs-12-31 MuiGrid-grid-sm-6-38 MuiGrid-grid-lg-4-62 container" data-reactid="5">
      <div class="MuiPaper-root-84 MuiPaper-shadow2-88 MuiPaper-rounded-85" data-reactid="6">
        <header data-reactid="7">
          <h1 data-reactid="8">Todo List</h1>
          <form data-reactid="9">
            <div class="MuiFormControl-root-111" style="width:100%;" data-reactid="10">
              <label class="MuiFormLabel-root-121 MuiInputLabel-root-115 MuiInputLabel-formControl-116 MuiInputLabel-animated-119" data-reactid="11">
                <!-- react-text: 12 -->Type to add new tasks
                <!-- /react-text -->
              </label>
              <div class="MuiInput-root-125 MuiInput-formControl-126 MuiInput-inkbar-127 MuiInput-underline-133" data-reactid="13">
                <input type="text" class="MuiInput-input-129 MuiInput-inputSingleline-136" value="" name="text" data-reactid="14">
              </div>
            </div>
          </form>
        </header>
        <!-- react-empty: 15 -->
      </div>
    </div>
  </div>
</div>

Here is the repo I can reproduce it with: https://github.com/rangeoshun/meteor-react-tasks

Here I do the client side: MainClient.jsx

And here is the server-side: MainServer.jsx

I had a version where I compiled the ui as a string not using the ssrwpo:ssr package, but it behaved the same.

Any ideas? Thanks!

@rangeoshun Your server is using NODE_ENV=production while your client is using NODE_ENV=development.

Well, thanks! I thought this might be due to something like this, but have never thought of exactly this!

Thanks mate!

Cheers!

I have similar problem with [email protected] and [email protected]. What is important to note is that in React 16 rehydrating on client doesn't refresh className prop (in [email protected] did) so this "warning" can completely destroy layout.

Anyway I verified that in my case NODE_ENV is not an issue, both server and client has NODE_ENV=development.

Also theme provider is set with sheetsManager <MuiThemeProvider theme={theme} sheetsManager={new Map()}>.

I digged deeper and removed all unnecessary code to find that this warning is caused by Button and IconButton components.

Repo with minimal component showing an issue

Generally I get MuiGrid-typeItem mismatch warning but when I remove IconButton warning changes to MuiTouchRipple-root mismatch. When I remove Button component or whole Grid everything is ok.

It's strange that such issue can be caused by combination of Grid and Button components. Probably I have some problem in configuration but maybe there is some solution to inform developer of an issue to avoid such cases in future?

Also any tips how to debug this?

@R0bson Sorry, I can't reproduce it with your reproduction link.

I forgot to mark that reproducible code is on masterial-ui-grid-ssr-bug branch. May this be a problem?

Also my environment details.
Node: v6.10.0
NPM: 3.10.10
OS: Ubuntu 16.04.3 LTS

Let me know it there is a mismatch.

Thank you for fast reponse.

--- EDIT ---
Full steps to reproduce:

git clone https://github.com/R0bson/redux-first-router-boilerplate.git rfr-mui
cd rfr-mui
git fetch
git checkout masterial-ui-grid-ssr-bug
npm install
npm start

Wait for webpack to finish build and go to http://localhost:3000

@R0bson This issue is coming from "jss": "^9.0.0",. We use v8.

Right... Removing jss and react-jss from package.json helped.

I've got to this issue because of eslint's import/no-extraneous-dependecies which requires to list all used dependencies in package.json dependencies.

I think that it's worth to add in documentation about SSR information to install exact versions of jss and react-jss or at least some note on eslint.

I can to this but I don't know which way is preferred. First requires additional documentation management on upgrading dependencies but the second one may still lead to the same issue because of direct installing those dependencies.

Thank you for help!

@kof For this issue, I think that we can add a jss.version check. We could assert that the provided jss instance version matches the one Material-UI relies on. Or at least the major version is identical. Yeah, I think that it will make it, I'm on it.

No, actually this warning won't help as the JSS version diff occurs going from the server to the client. Maybe we could add JSS as a peer dependency. And as we rely on the jss version of react-jss. We might also need to require jss directly.

And as we rely on the jss version of react-jss. We might also need to require jss directly.

Good, it's what @alitaheri is doing https://github.com/callemall/material-ui/pull/8479/files#diff-579da44d8bf8da76dcc331a87958265bR12

@R0bson Nobody read the docs. I fear it won't help much. But a small note about it won't harm :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sjstebbins picture sjstebbins  路  71Comments

tleunen picture tleunen  路  59Comments

iceafish picture iceafish  路  62Comments

cfilipov picture cfilipov  路  55Comments

darkowic picture darkowic  路  62Comments