MUI Stepper的StepIconComponent无法渲染styles对象样式导致应用崩溃
问题原因
你的代码存在3个核心错误,才会触发报错和样式失效:
- 类名拼写不匹配:你在styles中定义的图片样式类为
checklistImage,但在img标签上调用时写成了checkListImage,大小写不一致导致读取不到对应样式 - 自定义图标组件作用域冲突:你在
Checklist组件内部定义的ColorlibStepIcon,参数里重复声明了classes变量,覆盖了外层Checklist组件注入的样式类,同时没有根据MUI传入的active/completed状态拼接对应样式类 - 版本适配错误:你用的是Material UI v4版本,参考的demo是MUI v5版本的写法,v4不存在
@mui/material/styles下的styled导出,同时ownerState是v5 styled组件的专属属性,原生div不需要也不识别这个属性
修改后的可用代码
import React from 'react'; import { Typography } from '@material-ui/core'; import { withStyles } from '@material-ui/core/styles'; import Stepper from '@material-ui/core/Stepper'; import Step from '@material-ui/core/Step'; import StepLabel from '@material-ui/core/StepLabel'; import PropTypes from 'prop-types'; const styles = theme => ({ stepLabelRoot: { fontWeight: 'bold', color: '#fff', display: 'flex', flexDirection: 'column', alignItems: 'center' }, checklistHeader: { fontWeight: 'bold', marginTop: '80px', color: 'white' }, stepper: { background: 'none', fontWeight: 'bold', height: '500px' }, // 新增图标容器的基础样式 stepIconRoot: { backgroundColor: theme.palette.mode === 'dark' ? theme.palette.grey[700] : '#ccc', zIndex: 1, color: '#fff', width: 50, height: 50, display: 'flex', borderRadius: '50%', justifyContent: 'center', alignItems: 'center', }, // 激活、完成状态的样式 active: { backgroundImage: 'linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)', boxShadow: '0 4px 10px 0 rgba(0,0,0,.25)', }, completed: { backgroundImage: 'linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)', }, checklistImage: { width: '42px', height: '42px' } }); const steps = ['Are you there?', 'Adopt', 'Buy']; const Checklist = ({ classes }) => { // 移除参数中的重复classes声明,直接用外层的classes const ColorlibStepIcon = ({ icon, completed, className, active }) => { const icons = { 1: <img className={classes.checklistImage} src="https://i.pinimg.com/474x/be/54/bd/be54bd5e8e9c23e3ce570ff2acae592d.jpg" alt="check" />, 2: <img className={classes.checklistImage} src="https://i.pinimg.com/474x/be/54/bd/be54bd5e8e9c23e3ce570ff2acae592d.jpg" alt="check" />, 3: <img className={classes.checklistImage} src="https://i.pinimg.com/474x/be/54/bd/be54bd5e8e9c23e3ce570ff2acae592d.jpg" alt="check" />, }; // 拼接状态对应的样式类 const rootClasses = [classes.stepIconRoot, className]; if (active) rootClasses.push(classes.active); if (completed) rootClasses.push(classes.completed); return ( <div className={rootClasses.join(' ')}> {icons[String(icon)]} </div> ); }; return ( <React.Fragment> <Typography variant="h6" align="center" gutterBottom className={classes.checklistHeader}>Check the following</Typography> <Stepper alternativeLabel activeStep={2} className={classes.stepper}> {steps.map(label => ( <Step key={label}> <StepLabel classes={{ root: classes.stepLabelRoot }} StepIconComponent={ColorlibStepIcon}> <div> {label} </div> <span> Lorem Ipsum </span> </StepLabel> </Step> ))} </Stepper> </React.Fragment> ); }; Checklist.propTypes = { classes: PropTypes.object.isRequired }; export default withStyles(styles, { withTheme: true })(Checklist);
额外说明
如果你想在v4中使用styled写法,可以导入import { styled } from '@material-ui/core/styles'使用,语法和v5基本一致,不需要改用withStyles实现。
内容的提问来源于stack exchange,提问作者Kenny Quach
相关产品推荐
相关产品推荐

