使用Material-UI withStyles HOC时为何需default导出?能否组件内调用?
关于Material-UI withStyles高阶组件的常见问题解答
1. 并非必须用default导出组件
withStyles作为高阶组件(HOC),本质是接收一个组件作为参数,返回一个注入了classes props的新组件。它和ES模块的导出方式没有绑定关系,你完全可以对处理后的组件做命名导出,不需要局限于默认导出。
如果想在同一个文件里导出多个带样式的组件,正确写法如下:
// Cards.js import React from "react"; import { Card, withStyles } from "@material-ui/core"; const styles = theme => ({ card: { margin: theme.spacing(2) }, anotherCard: { margin: theme.spacing(4) } }); // 定义基础组件 function CustomCard({ classes }) { return <Card className={classes.card}>我是命名导出的组件</Card>; } function AnotherCard({ classes }) { return <Card className={classes.anotherCard}>我也是命名导出的组件</Card>; } // 用withStyles包裹后命名导出 export const CustomCard = withStyles(styles)(CustomCard); export const AnotherCard = withStyles(styles)(AnotherCard); // Elsewhere.js 中直接命名导入 import { CustomCard, AnotherCard } from "./Cards";
也可以简化为直接在导出时完成包裹:
export const CustomCard = withStyles(styles)(({ classes }) => ( <Card className={classes.card}>我是命名导出的组件</Card> )); export const AnotherCard = withStyles(styles)(({ classes }) => ( <Card className={classes.anotherCard}>我也是命名导出的组件</Card> ));
2. 绝对不能在组件return语句中直接调用withStyles
你尝试的return withStyles(styles)(<Card/>)写法完全错误,核心原因有两点:
withStyles返回的是一个组件函数/类,不是可直接渲染的React元素。即便你改成<withStyles(styles)(Card) />,也会导致每次组件渲染时都创建全新的组件实例,触发重复的卸载/挂载操作,严重影响性能,还会丢失组件内部状态。withStyles的作用是将处理后的classes注入到被包裹组件的props中,直接传入React元素的话,根本无法获取到classes——因为classes是为组件设计的注入属性,不是给元素用的。
3. 你忽略的核心特性
- 高阶组件的本质:HOC是组件的"增强工厂",用来包装组件以扩展功能,不是渲染阶段的工具函数,必须在组件定义阶段完成包裹,而非渲染阶段。
- ES模块的灵活性:默认导出和命名导出只是ES模块的两种导出形式,和HOC的使用没有强制绑定关系,如何导出完全取决于你对HOC返回结果的处理方式。
内容的提问来源于stack exchange,提问作者RobGo
相关产品推荐
相关产品推荐

