React中Material UI自定义TextField挂载及语言切换不显示数据问题
问题根源
你封装的CustomTextField出现无法响应外部数据变化的问题,核心原因是内部维护的状态没有和外部传入的prop同步:
- 组件仅在初始化时用
useState(text)把传入的text作为内部value的初始值,后续父组件传入的text更新时(比如页面首次加载完成数据返回、切换语言触发text变化),内部的value状态不会同步更新,所以始终显示初始值(如果初始传入空就是空白)。 - 原生MUI TextField是标准受控组件,直接使用外部传入的
value渲染,本身不维护独立状态,所以外部状态变化会直接响应。
修复方案
方案1(推荐):改成完全受控组件,和原生MUI行为对齐
直接删除内部冗余的状态,所有状态交给父组件管理,代码调整如下:
const CustomTextField = (props: TextFieldProps) => { const { label, text, width, onChangeHandler, disabled, id = "textFieldDefault" } = props; const classes = useStyles({ textFieldWidth: width }); const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { onChangeHandler(event); }; return ( <div> <div> <Typography id={"text-field-label-" + label} component="label" htmlFor={id} variant="caption" > {label} </Typography> </div> <MaterialTextField id={id} onChange={handleChange} className={classes.textField} variant="outlined" margin="normal" size="small" // 直接使用外部传入的text,不经过内部state value={text} disabled={disabled} /> </div> ); };
额外建议:可以把props中的text字段改名为value,和MUI原生组件的属性命名保持一致,降低使用时的理解成本。
方案2:保留内部状态,同步外部prop变化
如果有特殊场景需要组件内部维护状态,就添加useEffect监听外部text的变化,同步更新内部状态:
const CustomTextField = (props: TextFieldProps) => { const { label, text, width, onChangeHandler, disabled, id = "textFieldDefault" } = props; const classes = useStyles({ textFieldWidth: width }); const [value, setValue] = React.useState<string>(text); // 添加这行监听外部text变化,同步到内部state React.useEffect(() => { setValue(text); }, [text]); const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { setValue(event.target.value); onChangeHandler(event); }; // 其余返回代码不变 };
这种方案需要注意避免外部prop和内部状态的更新冲突,若非必要优先使用方案1。
内容的提问来源于stack exchange,提问作者MattoMK
相关产品推荐
相关产品推荐

