Warning: Prop `className` did not match. Server: "MuiAvatar-img-154" Client: "MuiAvatar-img-148"
See original GitHub issueWhen 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:
- Created 5 years ago
- Comments:16
Top 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 >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@riddla Yes, I have solved it.
@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?