Reputation: 11
I am trying to use react.js with material-ui. However, my event handlers do not seem to work.
For example, I tried playing around with the boilerplate material js file: (https://github.com/mui-org/material-ui/blob/master/docs/src/pages/demos/lists/NestedList.js )
The handleclick function does not work in my application (i.e. clicking on it does not collapse the list).
Th one major difference is that I used the code in a jsx file instead of js (however, changing the file to js does not solve the problem).
my code:
import React, {Component} from 'react'
import { List, ListItem, ListItemText, Collapse, Typography } from '@material-ui/core'
import { ExpandLess, ExpandMore } from '@material-ui/icons'
import { withStyles } from '@material-ui/core/styles';
const styles = theme => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: theme.palette.secondary,
},
nested: {
paddingLeft: theme.spacing.unit * 4,
},
});
class NestedList extends Component {
constructor(props){
super(props);
this.state = { open: true };
};
handleClick = () => {
this.setState(state => ({ open: !this.state.open }));
};
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<List
component="nav"
>
<ListItem>
<ListItemText
disableTypography
primary={<Typography type="subheadling" style={{ color: 'white' }}>Favourite</Typography>}
/>
</ListItem>
<ListItem button onClick={this.handleClick}>
<ListItemText
disableTypography
primary={<Typography type="subheadling" style={{ color: 'white' }}>Playlists</Typography>}
/>
{this.state.open ? <ExpandLess style={{ color: 'white' }} /> : <ExpandMore style={{ color: 'white' }} />}
</ListItem>
<Collapse in={this.state.open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button className={classes.nested}>
<ListItemText
disableTypography
primary={<Typography type="subheadling" style={{ color: 'white' }}>{`p1`}</Typography>}
/>
</ListItem>
<ListItem button className={classes.nested}>
<ListItemText
disableTypography
primary={<Typography type="subheadling" style={{ color: 'white' }}>{`p2`}</Typography>}
/>
</ListItem>
</List>
</Collapse>
</List>
</div>
);
}
}
export default withStyles(styles)(NestedList);
Update I suspect there is something wrong with the onClick Event since click is not listed as an event listener on the browser.
Upvotes: 0
Views: 3383
Reputation: 11
Thanks to everyone for the help. I really appreciate the help from @Leogoesger and @CaseyC. Made me realize what's working in my code and where to debug for errors.
So the reason that the event handler didn't work is because I only rendered my Material-ui files on the server side and renderToString()
stripped out all the event handlers.
I followed the instruction here: https://material-ui.com/guides/server-rendering/ and managed to get my App working.
Upvotes: 0
Reputation: 3820
Here is the working example of your code: https://codesandbox.io/s/k2nkj8705r
Neither of the following solutions might be what you are looking for, but here are a couple things you might want to watch out for:
Using handleEvent = () => {}
is part of the babel-plugin-transform-class-properties
. This gives you the implicit binding so you dont have to bind it youself. Otherwise, typically you will have to write differently like the following.
handleClick {
this.setState(state => ({ open: !this.state.open }));
};
Then whenever you need to to use it, you have two options. Option 1 via bind
. You can do that in your constructor
.
this.handleClick = this.handleClick.bind(this);
Or(example onClick
in a div
). Another approach is to create a new function for every instance, not very efficient.
<div onClick={() => this.handleClick()}>Click me</div>
Although not a problem, setState is like this.
handleClick = () => {
this.setState({ open: !this.state.open });
};
When calling setState
, you just need to pass in an object.
Upvotes: 2
Reputation: 439
You forgot to bind your handleClick
on your constructor, add this line to the bottom of your constructor this.handleClick = this.handleClick.bind(this);
.
I just notice that you use handleClick = () => { ... }
, if the babel was configured properly the binding won't be needed anymore, but let's try it and let me know if it's working or not
Upvotes: 1