MUI5 React TextField条件错误颜色修改及警告消除问询
我想要为MUI5的TextField组件设置条件化错误颜色(警告橙色、错误红色),且不想使用MUI5中已废弃的useStyle。编写的代码如下:
import { TextField as MuiTextField } from "@mui/material"; const TextField = styled(MuiTextField)(({ theme, isWarning }) => ({ "& .MuiOutlinedInput-root": { "&.Mui-error": { "& fieldset": { borderColor: isWarning ? theme.palette.warning.main : theme.palette.error.main, }, "&:hover fieldset": { borderColor: isWarning ? theme.palette.warning.main : theme.palette.error.main, }, "&.Mui-focused fieldset": { borderColor: isWarning ? theme.palette.warning.main : theme.palette.error.main, }, }, }, }));
使用方式:
<TextField label="Description" name="description" value={this.state.description} onChange={this.handleChange} error={Boolean(errors?.description)} isWarning={this.state.isWarning} />
功能可正常运行,但控制台出现警告:
Warning: React does not recognize the
isWarningprop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercaseiswarninginstead. If you accidentally passed it from a parent component, remove it from the DOM element.
改为小写iswarning后又出现错误:
Received
truefor a non-boolean attributeiswarning.
请问如何消除这些日志,或是否有其他修改颜色的方案?
方法一:过滤自定义props,避免传递给底层DOM元素
问题根源是styled组件会把所有接收的props传递给底层的MuiTextField,而isWarning不是TextField的原生props,最终会被传到DOM元素上导致警告。可以通过解构分离出自定义props,只把剩余props传给组件:
import { TextField as MuiTextField } from "@mui/material"; import { styled } from "@mui/material/styles"; const TextField = styled(({ isWarning, ...props }) => <MuiTextField {...props} />)(({ theme, isWarning }) => ({ "& .MuiOutlinedInput-root": { "&.Mui-error": { "& fieldset": { borderColor: isWarning ? theme.palette.warning.main : theme.palette.error.main, }, "&:hover fieldset": { borderColor: isWarning ? theme.palette.warning.main : theme.palette.error.main, }, "&.Mui-focused fieldset": { borderColor: isWarning ? theme.palette.warning.main : theme.palette.error.main, }, }, }, }));
先通过匿名组件剥离isWarning,只传递其他合法props给MuiTextField,自定义prop就不会被传到DOM元素上,警告自然消失。
方法二:使用sx prop直接内联样式(轻量方案)
如果不想封装styled组件,可直接在使用TextField时通过sx prop动态设置样式,无需额外封装:
import { TextField } from "@mui/material"; // 使用时 <TextField label="Description" name="description" value={this.state.description} onChange={this.handleChange} error={Boolean(errors?.description)} sx={{ "& .MuiOutlinedInput-root.Mui-error fieldset": { borderColor: this.state.isWarning ? "warning.main" : "error.main", }, "& .MuiOutlinedInput-root.Mui-error:hover fieldset": { borderColor: this.state.isWarning ? "warning.main" : "error.main", }, "& .MuiOutlinedInput-root.Mui-error.Mui-focused fieldset": { borderColor: this.state.isWarning ? "warning.main" : "error.main", }, }} />
这种方式直接根据状态切换颜色,不会产生prop传递的问题。
方法三:自定义主题变体(全局复用场景)
如果需要在多个地方复用该样式,可通过自定义MUI主题扩展TextField的变体:
import { createTheme, ThemeProvider } from "@mui/material/styles"; import { TextField } from "@mui/material"; const theme = createTheme({ components: { MuiTextField: { variants: [ { props: { error: true, variant: "outlined" }, style: ({ theme, ownerState }) => ({ "& .MuiOutlinedInput-root.Mui-error fieldset": { borderColor: ownerState.isWarning ? theme.palette.warning.main : theme.palette.error.main, }, "& .MuiOutlinedInput-root.Mui-error:hover fieldset": { borderColor: ownerState.isWarning ? theme.palette.warning.main : theme.palette.error.main, }, "& .MuiOutlinedInput-root.Mui-error.Mui-focused fieldset": { borderColor: ownerState.isWarning ? theme.palette.warning.main : theme.palette.error.main, }, }), }, ], }, }, }); // 使用时包裹在ThemeProvider中 <ThemeProvider theme={theme}> <TextField label="Description" name="description" value={this.state.description} onChange={this.handleChange} error={Boolean(errors?.description)} isWarning={this.state.isWarning} /> </ThemeProvider>
注意此方法仍需配合方法一的props过滤逻辑,避免isWarning被传递到DOM元素。
内容的提问来源于stack exchange,提问作者John

