React使用withStyles应用样式时报Objects are not valid as a React child错误如何解决
问题产生原因
- 核心错误:
withStyles是Material-UI提供的样式高阶组件,调用withStyles(styles)(组件)后返回的是新的组件对象,你在Form组件的return中直接返回了这个组件对象,而非将其作为JSX标签渲染,React尝试将对象作为子元素渲染时就触发了「Objects are not valid as a React child」的报错。 - 额外错误点:
- 在函数组件内部定义被高阶组件包裹的组件,会导致每次Form渲染时都生成全新的组件实例,出现状态丢失、不必要重渲染的问题。
- 样式类名绑定错误:
className="classes.bottom-gap"是静态字符串,没有真正取到注入的classes对象值,且styles中定义的类名key是bottomgap,和使用的bottom-gap名称不匹配。 - 表单控件的
value、onChange属性错误绑定到了FormControl上,应该绑定到内部的输入组件(TextField、Switch)上。
修复方案
- 将样式定义、被withStyles包裹的组件逻辑全部提到Form组件外部,生成独立的带样式组件。
- 在Form组件内部将带样式组件作为JSX标签渲染,通过props传递需要的状态和方法。
- 修正类名绑定、表单属性绑定的错误写法。
修复后完整代码如下:
import { useState } from 'react'; import { withStyles, Grid, FormControl, TextField, FormControlLabel, Switch } from '@material-ui/core'; const styles = { bottomgap: { marginBottom: "10px" } }; // 带样式的表单内容组件,定义在Form外层 const StyledFormContent = withStyles(styles)(({ classes, project, handleChange, handlePermisson }) => { return ( <div> <Grid container> <Grid item md={6}> <FormControl className={classes.bottomgap} fullWidth > <TextField id="project_id" label="Project id" variant="outlined" value={project.id} onChange={handleChange("id")} /> </FormControl> <FormControl fullWidth > <TextField id="project_name" label="Project name" variant="outlined" value={project.name} onChange={handleChange("name")} /> </FormControl> <FormControl fullWidth > <FormControlLabel control={<Switch checked={project.isPublic} onChange={handlePermisson("isPublic")} />} label="Is Public" /> </FormControl> </Grid> <Grid item md={6}></Grid> </Grid> </div> ); }); const Form = () => { const [project, setProject] = useState({ id: "", name: "", isPublic: false }); const handleChange = (prop) => (event) => { setProject({ ...project, [prop]: event.target.value }); }; const handlePermisson = (prop) => (event) => { setProject({ ...project, [prop]: event.target.checked }); }; // 作为JSX标签渲染带样式组件,传入所需参数 return <StyledFormContent project={project} handleChange={handleChange} handlePermisson={handlePermisson} />; }; export default Form;
内容的提问来源于stack exchange,提问作者Swaroop Maddu
相关产品推荐
相关产品推荐

