TypeScript开发React时条件应用CSS样式不生效问题咨询
问题原因与修复方案
- 样式对象与CSS类名混淆:你定义的
BoxStyles、BoxStylesActive是TS类型的样式对象,不是全局CSS类名,classNames方法仅用于拼接字符串格式的CSS类名,传样式对象完全不生效。 - sx属性优先级更高:MUI组件的
sx属性样式优先级高于className传入的样式,就算你正确绑定了类名,只要sx内有冲突的边框定义,类名样式也会被覆盖。 - 样式逻辑错误:你写的默认态和激活态边框都是黑色,就算逻辑生效也看不出切换效果。
- 函数组件参数错误:React函数组件第二个参数是ref转发的预留参数,不是自定义props,你解构的
{active}根本拿不到对应值,需要这个属性要写到BigButtonProps接口里。 - 父组件点击事件未触发:你在点击回调里只执行了内部的
clickMe方法,没有调用props.onClick,父组件绑定的点击逻辑会失效。
修复后完整代码
import { useState, FC } from 'react'; import { Box, Typography, SvgIcon } from '@mui/material'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import type { CSS } from '@mui/material'; interface BigButtonProps { onClick(): void; Title: string; Description?: string; startIcon?: React.ElementType; } const BigButton: FC<BigButtonProps> = (props) => { const [isClicked, setClicked] = useState(false); const clickMe = () => { setClicked(!isClicked); console.log("say hello"); // 触发父组件传入的点击事件 props.onClick(); }; return ( <Box sx={{ height: { xs: "45px", md: "100px", }, width: { xs: "45px", md: "300px", }, borderRadius: "10px", boxShadow: "0 2px 3px 2px rgba(0, 0, 0, .125)", display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column", // 边框逻辑直接写在sx里,默认是灰色边框,点击后保持黑色 border: isClicked ? "1.5px solid black" : "1.5px solid #e0e0e0", ":hover": { border: "1.5px solid blue", }, }} onClick={clickMe} > <Typography variant="h1">{props.Title}</Typography> <Typography variant="subtitle1">{props.Description}</Typography> <SvgIcon component={CheckCircleIcon} sx={{ display: "block", }} /> </Box> ); }; export default BigButton;
如果需要保留className的写法,你可以把BoxStyles、BoxStylesActive改成全局CSS类,写到项目的CSS文件里再用classNames拼接,不过直接在sx里写逻辑是MUI更推荐的实现方式。
内容的提问来源于stack exchange,提问作者joekevinrayan96
相关产品推荐
相关产品推荐

