使用Material-UI自定义iOS风格Switch时classes未定义问题排查
问题原因:缺少Material-UI的
withStyles高阶组件注入 你遇到的classes为undefined的核心原因是:你的ListRow组件没有被Material-UI的withStyles高阶组件包裹。Material-UI的自定义样式系统依赖withStyles来将你定义的styles对象转换为实际可用的CSS类名,并通过props注入到组件中,没有这一步,组件自然拿不到classes属性。
解决方案步骤
1. 导入withStyles
首先确保在ListRow组件文件顶部导入withStyles:
import { withStyles } from '@material-ui/core/styles';
2. 用withStyles包裹ListRow组件
在组件定义完成后,不要直接导出原始组件,而是用withStyles把你的styles对象和组件绑定,再导出:
// 你的ListRow组件定义... // 替换原来的export语句 export default withStyles(styles)(ListRow);
3. 确认组件逻辑的正确性
从你提供的代码来看,render里const { classes } = this.props;的写法是正确的,只要完成前两步,classes就会被正确注入。另外也要确保你的change方法已经在组件内定义(比如作为类方法或箭头函数绑定this),避免后续出现新的报错。
修改后的ListRow核心代码示例
import React from 'react'; import { withStyles } from '@material-ui/core/styles'; import Switch from '@material-ui/core/Switch'; import moment from 'moment'; const styles = theme => ({ iOSSwitchBase: { '&$iOSChecked': { color: theme.palette.common.white, '& + $iOSBar': { backgroundColor: '#52d869', }, }, transition: theme.transitions.create('transform', { duration: theme.transitions.duration.shortest, easing: theme.transitions.easing.sharp, }), }, iOSChecked: { transform: 'translateX(15px)', '& + $iOSBar': { opacity: 1, border: 'none', }, }, iOSBar: { borderRadius: 13, width: 42, height: 26, marginTop: -13, marginLeft: -21, border: 'solid 1px', borderColor: theme.palette.grey[400], backgroundColor: theme.palette.grey[50], opacity: 1, transition: theme.transitions.create(['background-color', 'border']), }, iOSIcon: { width: 24, height: 24, }, iOSIconChecked: { boxShadow: theme.shadows[1], }, }); class ListRow extends React.Component { // 定义change方法(示例) change = (event, checked) => { // 这里处理开关状态变化逻辑 this.props.toggleSwitch(this.props.rowItems.id, checked); }; render() { const { classes } = this.props; const dateDisplay = moment(this.props.createdAt).format('MMM YYYY'); if (this.state.show) { return ( <tr className="experiment-list__row" onMouseDown={() => this.props.onRowHovered(this.props.rowItems.id)}> <td>{this.props.rowItems.name}</td> <td>{this.props.rowItems.owner}</td> <td>{dateDisplay}</td> <td className="experiment-list--col__switch"> <Switch classes={{ switchBase: classes.iOSSwitchBase, bar: classes.iOSBar, icon: classes.iOSIcon, iconChecked: classes.iOSIconChecked, checked: classes.iOSChecked, }} disableRipple onClick={e => e.preventDefault()} checked={this.props.rowItems.status} onChange={this.change} /> </td> </tr> ); } else { return null; } } } // 关键:用withStyles包裹后导出组件 export default withStyles(styles)(ListRow);
这样修改后,classes就会被正确传递到ListRow组件中,你定义的iOS风格Switch样式就能正常生效了。
内容的提问来源于stack exchange,提问作者Dawn17
相关产品推荐
相关产品推荐

