question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Warning: Prop `className` did not match. Server: "MuiAvatar-img-154" Client: "MuiAvatar-img-148"

See original GitHub issue

When I use SSR to render my page, I found that only <Avatar> would have this warning. Other Components are working perfectly. More source code can be found in my repository cnode-proxy. Please help me.

import React from 'react';
import PropTypes from 'prop-types';
import ListItem from 'material-ui/List/ListItem';
import ListItemAvatar from 'material-ui/List/ListItemAvatar';
import ListItemText from 'material-ui/List/ListItemText';
import Avatar from 'material-ui/Avatar';
import { withStyles } from 'material-ui/styles';
import { topicPrimaryStyle, topicSecondaryStyle } from './styles';
import { tabs } from '../../util/variable-define';
import cx from 'classnames';
import dateFormat from 'dateformat';

const Primary = ({ classes, topic }) => {
  const classNames = cx({
    [classes.tab]: true,
    [classes.top]: topic.top,
  });
  return (
    <span className={classes.root}>
      <span className={classNames}>{topic.top ? 'Top' : tabs[topic.tab]}</span>
      <span className={classes.title}>{topic.title}</span>
    </span>
  );
};

Primary.propTypes = {
  classes: PropTypes.object.isRequired,
  topic: PropTypes.object.isRequired,
};

const StyledPrimary = withStyles(topicPrimaryStyle)(Primary);

const Secondary = ({ classes, topic }) => (
  <span className={classes.root}>
    <span className={classes.userName}>{topic.author.loginname}</span>
    <span className={classes.count}>
      <span className={classes.replyCount}>Reply: {topic.reply_count}</span>
      <span>Visiting: {topic.visit_count}</span>
    </span>
    <span>Date: {dateFormat(topic.create_at, 'yy-mm-dd')}</span>
  </span>
);

Secondary.propTypes = {
  classes: PropTypes.object.isRequired,
  topic: PropTypes.object.isRequired,
};

const StyledSecondary = withStyles(topicSecondaryStyle)(Secondary);

const TopicListItem = ({ onClick, topic }) => (
  <ListItem button onClick={onClick}>
    <ListItemAvatar>
//Error would happend here
      <Avatar src={topic.author.avatar_url} />
    </ListItemAvatar>
    <ListItemText
      primary={<StyledPrimary topic={topic} />}
      secondary={<StyledSecondary topic={topic} />}
    />
  </ListItem>
);

TopicListItem.propTypes = {
  onClick: PropTypes.func.isRequired,
  topic: PropTypes.object.isRequired,
};

export default TopicListItem;

import React from 'react';
import { observer, inject } from 'mobx-react';
import PropTypes from 'prop-types';
import Helmet from 'react-helmet';
import Container from '../layout/container';
import Tabs, { Tab } from 'material-ui/Tabs';
import TopicListItem from './list-item';
import List from 'material-ui/List';
import { CircularProgress } from 'material-ui/Progress';
import queryString from 'query-string';
import { tabs } from '../../util/variable-define';

@inject((stores) => {
  return {
    appState: stores.appState,
    topicStore: stores.topicStore,
  };
})
@observer
export default class TopicList extends React.Component {
  static contextTypes = {
    router: PropTypes.object,
  };
  constructor() {
    super();
    this.onTabChange = this.onTabChange.bind(this);
    this.onListItemClick = this.onListItemClick.bind(this);
  }
  componentDidMount() {
    const tab = this.getTab();
    this.props.topicStore.fetchTopics(tab);
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.location.search !== this.props.location.search) {
      this.props.topicStore.fetchTopics(this.getTab(nextProps.location.search));
    }
  }
  onTabChange(e, value) {
    this.context.router.history.push({
      pathname: '/list',
      search: `?tab=${value}`,
    });
  }
  onListItemClick(topic) {
    this.context.router.history.push(`/detail/${topic.id}`);
  }
  getTab(search) {
    const searchString = search || this.props.location.search;
    const query = queryString.parse(searchString);
    return query.tab || 'all';
  }
  bootstrap() {
    const query = queryString.parse(this.props.location.search);
    const tab = query.tab || 'all';
    const result = this.props.topicStore.fetchTopics(tab).then(() => {
      return true;
    }).catch(() => {
      return false;
    });
    return result;
  }
  render() {
    const {
      topicStore,
    } = this.props;
    const { syncing } = topicStore;
    const topicList = topicStore.topics;
    const { createdTopic } = topicStore;
    const { user } = this.props.appState;
    const tab = this.getTab();
    return (
      <Container>
        <Helmet>
          <title>Topic List</title>
        </Helmet>
        <div>
          <Tabs value={tab} onChange={this.onTabChange}>
            {
              Object.keys(tabs).map(tabKey => (
                <Tab key={tabKey} label={tabs[tabKey]} value={tabKey} />
              ))
            }
          </Tabs>
        </div>
        {
          createdTopic && createdTopic.length > 0 ?
            <List>
              {
                createdTopic.map((topic) => {
                  topic = Object.assign({}, topic, {
                    author: user.info,
                  });
                  return (
                    <TopicListItem key={topic.id} onClick={() => { this.onListItemClick(topic); }} topic={topic} />
                  );
                })
              }
            </List> :
            null
        }
        <List>
          {
            topicList.map(topic => (
              <TopicListItem
                key={topic.id}
                onClick={() => { this.onListItemClick(topic); }}
                topic={topic}
              />
            ))
          }
        </List>
        {
          syncing ? (
            <div style={{ display: 'flex', justifyContent: 'space-around', padding: '40px 0' }}>
              <CircularProgress color="secondary" size={100} />
            </div>
          ) : null
        }
      </Container>
    );
  }
}
TopicList.wrappedComponent.propTypes = {
  appState: PropTypes.object.isRequired,
  topicStore: PropTypes.object.isRequired,
};
TopicList.propTypes = {
  location: PropTypes.object.isRequired,
};

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:16

github_iconTop GitHub Comments

14reactions
gzcisco720commented, Apr 22, 2018

@riddla Yes, I have solved it.

9reactions
riddlacommented, Jul 31, 2018

@vpaul08, I finally found the solution for my problem. But it was closely related to the combination of nextjs and material-ui. Would it help you if I document it here?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Warning: Prop `className` did not match. when using styled ...
That error is showing you the class that is being created by your styled-components library on the server and how it is different...
Read more >
Warning: Prop className did not match. #7322 - GitHub
It appears to be an issue that backend generates styled component but client doesn't get it/doesn't use it and instead of using server...
Read more >
Fixing ClassName did not match error - DEV Community ‍ ‍
Warning : Prop `className` did not match. Server: Client: This is probably one of the most annoying problem with ...
Read more >
Solving the Styled Components Warning in Next.JS with Babel
Warning : Prop `className` did not match. Server: “fs-fdsf” Client: “sd-dfasj”. The combination of Next.JS and Styled Components is truly ...
Read more >
Prop `className` did not match - CodeSandbox
CodeSandbox is an online editor tailored for web applications. ... Prop `className` did not match. 0. Embed Fork Create Sandbox Sign in. Sandbox...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found