React-MaterialUI组件传多Props报错:TypeError: Cannot read property 'header' of undefined
解决React组件Props传递错误:TypeError: Cannot read property 'header' of undefined
咱们先把问题根源理清楚:你遇到的错误是因为**typo这个prop根本没被正确传入组件**,而且你对withStyles的用法理解有误。
错误原因拆解
withStyles的用法不对:withStyles是Material-UI的高阶组件,它只接受一个样式对象作为参数,用来把样式转化为classesprop传给组件。你把Typos(文本内容对象)作为第二个参数传给它,这完全不符合它的设计,所以这个参数会被忽略,typo自然不会被传入组件。- 组件需要的
typoprop未被提供:你在SurveyApp.propTypes里声明了typo是必填的object,但实际没有通过正确的方式把它传给组件,导致typo是undefined,访问typo.header就会抛出错误。
两种可行的解决方案
方案一:直接在组件内使用Typos(适合固定文本场景)
如果你的文本内容是固定不变的,不需要动态修改,直接在组件里导入Typos并使用即可,不需要把它作为prop传递:
修改后的App.js代码:
import React from 'react'; import PropTypes from 'prop-types'; import { withStyles } from 'material-ui/styles'; import Card, { CardActions, CardContent } from 'material-ui/Card'; import Typography from 'material-ui/Typography'; import './App.css'; import { AppStyle } from "./AppStyle"; import { Typos } from "./AppTypo"; // 直接导入文本内容 function SurveyApp(props) { const { classes } = props; return ( <div className={classes.wrapper}> <div className={classes._header}> </div> <div className={classes._body}> <div className={classes.__formContainer}> <Card className={classes.card}> <CardContent> <Typography> {Typos.header} {/* 直接使用Typos里的属性 */} </Typography> <Typography> {Typos.subHeader} </Typography> </CardContent> </Card> </div> </div> </div> ); } SurveyApp.propTypes = { classes: PropTypes.object.isRequired, // 移除typo的prop声明,因为不再需要通过props传递 } // withStyles只传入样式对象AppStyle export default withStyles(AppStyle)(SurveyApp);
方案二:通过组件Props传递typo(适合动态文本场景)
如果你的文本需要根据不同场景动态变化,那就需要把typo作为普通props传递给组件:
第一步,修正App.js的导出和prop声明:
import React from 'react'; import PropTypes from 'prop-types'; import { withStyles } from 'material-ui/styles'; import Card, { CardActions, CardContent } from 'material-ui/Card'; import Typography from 'material-ui/Typography'; import './App.css'; import { AppStyle } from "./AppStyle"; function SurveyApp(props) { const { classes, typo } = props; return ( <div className={classes.wrapper}> <div className={classes._header}> </div> <div className={classes._body}> <div className={classes.__formContainer}> <Card className={classes.card}> <CardContent> <Typography> {typo.header} </Typography> <Typography> {typo.subHeader} </Typography> </CardContent> </Card> </div> </div> </div> ); } SurveyApp.propTypes = { classes: PropTypes.object.isRequired, typo: PropTypes.object.isRequired } // withStyles只传入样式对象AppStyle export default withStyles(AppStyle)(SurveyApp);
第二步,在渲染SurveyApp的地方(比如index.js)传入typo prop:
import React from 'react'; import ReactDOM from 'react-dom/client'; import SurveyApp from './App'; import { Typos } from './AppTypo'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <SurveyApp typo={Typos} /> );
初学者小提醒
withStyles是专门处理Material-UI样式的工具,只负责把样式转化为classesprop,不要用它传递业务数据。- 组件的props分为两种:样式props(通过Material-UI的高阶组件处理)和业务数据props(通过组件标签直接传递),要区分开它们的传递方式。
内容的提问来源于stack exchange,提问作者Subrata Banerjee
相关产品推荐
相关产品推荐

