【问题标题】:className attribute won't take CSSProperties type - React, Material-UI, with TypeScript 4.1className 属性不会采用 CSSProperties 类型 - React、Material-UI、TypeScript 4.1
【发布时间】:2021-02-26 20:26:53
【问题描述】:

我是 Material-UI 的新手。我们使用 withStyles 来包装组件。

我按照文档here 创建了具有正确类型的类对象。

const classes = createStyles({
    mainDiv: {
        display: "flex",
        flexDirection: "column",
        justifyContent: "center"
        ...

然后我在 className 属性中将它们传递给我的组件,就像这样。

render() {
        const { classes } = this.props;
        return <div id="mainDiv" className={classes.mainDiv}>
        ...

我在 className 下收到一个 TypeScript 错误,上面写着:

Type 'CSSProperties | CreateCSSProperties&lt;{}&gt; | PropsFunc&lt;{}, CreateCSSProperties&lt;{}&gt;&gt;' is not assignable to type 'string | undefined'.

这个错误对我来说很有意义,因为在普通的 JSX 中,className 属性应该接收一个字符串。我觉得 Material-UI 传递一个对象很奇怪,但我想那是它的特殊之处。那么如何让 TypeScript 知道这个普通老 div 的 className 属性应该是同一个特殊的东西呢?

【问题讨论】:

    标签: reactjs typescript material-ui


    【解决方案1】:

    createStyles 函数不创建类名。它只是返回你给它的样式。它的唯一目的是通过强制样式符合CSSProperties 类型来检查样式的有效性。每the docs:

    TypeScript 拓宽了函数表达式的返回类型。因此,建议使用createStyles 辅助函数来构造您的样式规则对象。 createStyles 只是身份函数;它在运行时不会“做任何事情”,只是在编译时帮助指导类型推断。

    您需要将样式应用于style 属性而不是className 属性:

    return <div id="mainDiv" style={classes.mainDiv}/>
    

    或者使用创建string类名的不同函数,例如makeStyles:

    // creates a hook which maps props to class names
    const useStyles = makeStyles(classes);
    
    const MyComponent = (props: {}) => {
      // call the created hook with the component props
      const {mainDiv} = useStyles(props);
      // can use as className property
      return <div id="mainDiv" className={mainDiv} />;
    };
    

    当使用类组件和 withStyles 高阶组件时。您需要使用 WithStyles 类型实用程序为您的组件扩展 props 类型。像这样:

    import { WithStyles, createStyles } from '@material-ui/core';
    
    const styles = (theme: Theme) => createStyles({
      mainDiv: { ...  },
      button: { ... },
      ...
    });
    
    interface Props extends WithStyles<typeof styles> {
      foo: number;
      bar: boolean;
    }
    
    //or
    
    type Props = WithStyles<typeof styles> & {
      foo: number,
      bar: boolean
    }
    

    【讨论】:

    • 感谢您的回答。作为一个钩子,useStyles/makeStyles 仅适用于功能组件。你是说对于 Class 组件,唯一的解决方案是将样式对象传递给样式属性?
    • 类组件的makeStyles等价物是withStyles高阶组件:material-ui.com/styles/api/…
    • 然而,这就是我们正在做的事情。 export default withStyles(styles)(ClassComponent); 在那些文档中,它仍然显示将样式对象传递给渲染函数内的 className 道具(在包装在高阶组件中之前)。例如,&lt;div className={props.classes.root} /&gt;; 但是,这给了我在我的原始问题中提到的 TypeScript 错误。
    • 我在上面的答案中添加了一个编辑,它使用 WithStyles 类型实用程序提供了解决方案。
    猜你喜欢
    • 2017-11-06
    • 1970-01-01
    • 2018-06-04
    • 2020-02-04
    • 2018-05-08
    • 2022-08-20
    • 1970-01-01
    • 2021-11-18
    • 2021-11-02
    相关资源
    最近更新 更多