gpt4 book ai didi

reactjs - Material 用户界面 : Concise way to to define styled Components?

转载 作者:搜寻专家 更新时间:2023-10-30 21:11:53 24 4
gpt4 key购买 nike

我想找到一种使用 Material-UI 在我的应用中轻松定义便利组件的方法。

我从 Material-UI doco for Appbar 复制了一个例子并尝试引入一些 React 组件以增加可读性。

我的问题是关于 MenuShortcutBar 函数和下面的 MenuShortcutItem 类之间的样板对比。

MenuShortcutBar 相当简洁;但是一旦 Material-UI 样式出现,我最终需要大量的样板文件。我必须定义一个类、一个需要扩展 WithStyles 的属性接口(interface)和一个构造函数。

所以问题是:在使用 Material-UI 时,是否有一种简洁的方法来创建样式化的 React 组件?如何简化 MenuShortcutItem

import * as React from "react";
import {ReactNode, SyntheticEvent} from "react";
import {
AppBar,
Hidden,
IconButton,
Menu,
MenuItem,
SvgIcon,
Toolbar,
Typography,
withStyles,
WithStyles
} from "@material-ui/core";
import {SvgIconProps} from "@material-ui/core/SvgIcon";
import {SendMailSvg} from "component/svg-icon/SendMailSvg";

export interface MuiAppBarProps extends WithStyles<typeof styles> {

}

class MuiAppBar extends React.Component<
MuiAppBarProps,
{ anchorEl?: HTMLElement, }
>{

constructor(props: MuiAppBarProps, context?: any){
super(props, context);
this.state = {anchorEl: undefined}
}

handleMenu = (event:SyntheticEvent<HTMLElement>) => {
this.setState({ anchorEl: event.currentTarget });
};

handleClose = () => {
this.setState({ anchorEl: undefined });
};

render(){
const { classes } = this.props;
return <div className={classes.root}>
<AppBar position="static" color={"default"}>
<Toolbar variant={"dense"}>
<IconButton className={classes.menuButton} color="inherit">
<MenuIcon/>
</IconButton>
<IconButton className={classes.menuButton} color="inherit">
<SendMailSvg width={"2em"}/>
</IconButton>
<MenuShortcutBar>
<MenuShortcutItem classes={this.props.classes}>
Keywords
</MenuShortcutItem>
<MenuShortcutItem classes={this.props.classes}>
Forwarded
</MenuShortcutItem>
<MenuShortcutItem classes={this.props.classes}>
Rejected
</MenuShortcutItem>
</MenuShortcutBar>
</Toolbar>
</AppBar>
</div>
}
}

...

function MenuShortcutBar(props:{children: ReactNode}){
return <Hidden smDown>
{/* Avoid shortcuts wrapping which causes AppBar to grow in height */}
<span style={{
display: "flex", flexWrap: "nowrap", overflow: "hidden"
}}>
{props.children}
</span>
</Hidden>
}

interface MenuShortcutItemProps extends WithStyles<typeof styles> {
children: React.ReactNode
}
class MenuShortcutItem extends React.Component<
MenuShortcutItemProps,
any
>{
constructor(props: MenuShortcutItemProps, context?: any){
super(props, context);
}
render(){
return <IconButton color="inherit"
className={this.props.classes.menuButton}
>
{this.props.children}
</IconButton>
}
}

const styles = {
root: {
flexGrow: 1,
},
grow: {
flexGrow: 1,
},
menuButton: {
marginLeft: -12,
marginRight: 20,
},
};
export default withStyles(styles)(MuiAppBar);

最佳答案

Material-UI Typescript guide 中找到了一些信息这帮助我进行了更好的尝试。

感谢 Martin Hochel 的 Typescript pro tips帖子让我开始使用类型交集来混合 WithStyles进入 Prop 定义(我被挂断了尝试使用 extends )。

更简洁的函数式定义:

const MenuShortcutItem2 = withStyles(styles)((
props:{children:ReactNode} & WithStyles<typeof styles>
) => (
<IconButton className={props.classes.menuButton} color="inherit">
{props.children}
</IconButton>
));

还有一个相当简洁的类式组件定义,用于何时需要状态:

const ScreenContainer = withStyles(style)(class extends React.Component<
{children:ReactNode} & WithStyles<typeof style>
>{
state = {message: "wibble"} as {message?: string};
render(){
return <main className={this.props.classes.mainLayout}>
<Paper className={this.props.classes.paper}>
{this.props.children}
{this.state.message}
</Paper>
</main>
}
});

上面的一些问题:

  1. 重复中的重复 withStyles(styles)WithStyles<typeof styles>有点烦人。

  2. 在状态的定义中属性名称也有一些轻微的重复,但它仍然比标准的构造函数安排要好(无论如何你重复属性名称,但至少需要多三行样板文件).

关于reactjs - Material 用户界面 : Concise way to to define styled Components?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52677140/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com