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

Can't render a consistent classname on server and client [v1] #7836

Closed
Losses opened this issue Aug 19, 2017 · 18 comments
Closed

Can't render a consistent classname on server and client [v1] #7836

Losses opened this issue Aug 19, 2017 · 18 comments
Labels
core Infrastructure work going on behind the scenes

Comments

@Losses
Copy link
Contributor

Losses commented Aug 19, 2017

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
@oliviertassinari
Copy link
Member

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.

@istarkov
Copy link
Contributor

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

@oliviertassinari
Copy link
Member

Do you have a reproduction test case?

@istarkov
Copy link
Contributor

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

@oliviertassinari
Copy link
Member

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

@Losses
Copy link
Contributor Author

Losses commented Sep 1, 2017

@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.

@rangeoshun
Copy link

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!

@oliviertassinari
Copy link
Member

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

@rangeoshun
Copy link

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

Thanks mate!

Cheers!

@R0bson
Copy link

R0bson commented Oct 1, 2017

I have similar problem with material-ui@1.0.0-beta.12 and react@16.0.0. What is important to note is that in React 16 rehydrating on client doesn't refresh className prop (in react@15.6 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?

@oliviertassinari
Copy link
Member

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

@R0bson
Copy link

R0bson commented Oct 1, 2017

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

@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 1, 2017

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

@R0bson
Copy link

R0bson commented Oct 1, 2017

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!

@oliviertassinari
Copy link
Member

@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.

@oliviertassinari
Copy link
Member

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.

@oliviertassinari
Copy link
Member

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

@oliviertassinari
Copy link
Member

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

@oliviertassinari oliviertassinari added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Dec 21, 2022
@zannager zannager added core Infrastructure work going on behind the scenes and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Jan 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Infrastructure work going on behind the scenes
Projects
None yet
Development

No branches or pull requests

6 participants