using v4() on key property breaking styles
See original GitHub issueType of problem: bug?
Using a uuid as a key value looks to break the material-ui-styles. It seems material-ui is relying on an incrementing counter when using a key property in the component hierarchy.
For example, using v4() uuid in the following code breaks the material-ui styles:
import React from 'react';
import PropTypes from 'prop-types';
import {MenuList, MenuItem} from 'material-ui/Menu';
import Paper from 'material-ui/Paper';
import {withStyles} from 'material-ui/styles';
import {ListItemIcon, ListItemText} from 'material-ui/List';
import DraftsIcon from '@material-ui/icons/Drafts';
import SendIcon from '@material-ui/icons/Send';
import {NavLink} from 'react-router-dom';
import {connect} from 'react-redux'
import { withRouter } from 'react-router';
import {v4} from 'uuid';
import classNames from 'classnames';
const styles = theme => ({
menuItem: {
'&:focus': {
backgroundColor: theme.palette.primary.main,
'& $primary, & $icon': {
color: theme.palette.common.white
}
}
},
primary: {},
icon: {}
});
function Navigation(props) {
const {classes} = props;
console.log('Navigation',props)
return (<Paper>
<MenuList>
<NavLink to="/" className={props.classes.removeUnderline}>
<MenuItem className={classes.menuItem}>
{/* <ListItemIcon className={classes.icon}>
<SendIcon/>
</ListItemIcon> */}
<ListItemText classes={{
primary: classes.primary
}} inset={true} primary="Home"/>
</MenuItem>
</NavLink>
{props.services.map( s =>
<NavLink to={s.urlPattern} className={classNames(props.classes.removeUnderline)} key={v4()}>
<MenuItem className={classNames(classes.menuItem)}>
{/* <ListItemIcon className={classes.icon}>
<SendIcon/>
</ListItemIcon> */}
<ListItemText classes={{
primary: classes.primary
}} inset={true} primary={s.headerTitle}/>
</MenuItem>
</NavLink>
)}
</MenuList>
</Paper>);
}
Navigation.propTypes = {
classes: PropTypes.object.isRequired
};
Navigation = withStyles(styles)(Navigation);
export default withRouter(connect((state) => ({services: state.onshoreApp.services, isFetching : state.onshoreApp.isFetching}))(Navigation))
Changing the key property to use an incrementing counter instead fixes the styles.
import React from 'react';
import PropTypes from 'prop-types';
import {MenuList, MenuItem} from 'material-ui/Menu';
import Paper from 'material-ui/Paper';
import {withStyles} from 'material-ui/styles';
import {ListItemIcon, ListItemText} from 'material-ui/List';
import DraftsIcon from '@material-ui/icons/Drafts';
import SendIcon from '@material-ui/icons/Send';
import {NavLink} from 'react-router-dom';
import {connect} from 'react-redux'
import { withRouter } from 'react-router';
import {v4} from 'uuid';
import classNames from 'classnames';
const styles = theme => ({
menuItem: {
'&:focus': {
backgroundColor: theme.palette.primary.main,
'& $primary, & $icon': {
color: theme.palette.common.white
}
}
},
primary: {},
icon: {}
});
function Navigation(props) {
const {classes} = props;
console.log('Navigation',props)
return (<Paper>
<MenuList>
<NavLink to="/" className={props.classes.removeUnderline}>
<MenuItem className={classes.menuItem}>
{/* <ListItemIcon className={classes.icon}>
<SendIcon/>
</ListItemIcon> */}
<ListItemText classes={{
primary: classes.primary
}} inset={true} primary="Home"/>
</MenuItem>
</NavLink>
{props.services.map( (s,i) =>
<NavLink to={s.urlPattern} className={classNames(props.classes.removeUnderline)} key={i}>
<MenuItem className={classNames(classes.menuItem)}>
{/* <ListItemIcon className={classes.icon}>
<SendIcon/>
</ListItemIcon> */}
<ListItemText classes={{
primary: classes.primary
}} inset={true} primary={s.headerTitle}/>
</MenuItem>
</NavLink>
)}
</MenuList>
</Paper>);
}
Navigation.propTypes = {
classes: PropTypes.object.isRequired
};
Navigation = withStyles(styles)(Navigation);
export default withRouter(connect((state) => ({services: state.onshoreApp.services, isFetching : state.onshoreApp.isFetching}))(Navigation))
The styles that are breaking in this case is the background color of my navigation items:
how it looks with key={v4()}:
renders correctly using an incrementing counter key={i}:
Tech | Version |
---|---|
Material-UI | 1.0.0-beta.42 |
React | 16.2.0 |
browser | any |
etc |
Issue Analytics
- State:
- Created 5 years ago
- Comments:5 (2 by maintainers)
Top Results From Across the Web
using v4() on key property breaking styles #11084 - GitHub
Type of problem: bug? Using a uuid as a key value looks to break the material-ui-styles. It seems material-ui is relying on an...
Read more >Migrating to v5: getting started - Material UI - MUI
This guide explains how and why to migrate from Material UI v4 to v5. ... will automatically address many of the breaking changes...
Read more >Property accessors - JavaScript - MDN Web Docs - Mozilla
Property accessors provide access to an object's properties by using the dot notation or the bracket notation.
Read more >Style Props - Chakra UI
Learn how to use style props in Chakra UI. ... The following table shows a list of every style prop and the properties...
Read more >Upgrade Guide - Tailwind CSS
Tailwind CSS v3.0 is a major update to the framework with a brand new internal engine and as such includes a small number...
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
@Gribbs I was able to reproduce your issue in https://codesandbox.io/s/j7yjj1l9mw. This is a react question. When a link is pressed. It gets the CSS active state. The active state change the background color. Clicking a link also triggers a rerender. Given you are using
key={v4()}
, you will inject a new dom node at each render, losing the active state and the background color.⚠️ I fear you have set yourself a bad track record. Don’t expect us from answering your question in the future here. We will close them.
“Given you are using key={v4()}, you will inject a new dom node at each render”. Unless I’m missing something, it renders exactly the same amount of times whether I use key={i} or key={v4()} and there’s no extra dom nodes created? When I changed your example to use the array key it worked as expected https://codesandbox.io/s/mjly8xk52x !