自定义withStyles材质UI React样式的组件

时间:2018-12-03 17:13:37

标签: reactjs material-ui jss

我有一个材料UI样式的React组件库。

样式化的组件如下所示:

import React from "react";
import withStyles from "@material-ui/core/styles/withStyles";
import headerStyle from "material-kit-pro-react/assets/jss/material-kit-pro-react/components/headerStyle.jsx";

class Header extends React.Component {
    // ...
}
export default withStyles(headerStyle)(Header);

我想自定义组件的样式,但我希望保持库不变,以避免与将来的更新冲突。

所以我决定创建自己的组件:

import React from "react";
import withStyles from "@material-ui/core/styles/withStyles";
import Header from "material-kit-pro-react/components/Header/Header.jsx";

export default withStyles(theme => ({
    primary: {
        color: "#000"
    }
}))(Header);

但是,通过这种方法,JSS引擎为同一组件创建了两个类(Header-primary-25 WithStyles-Header--primary-12)。这不完全是一个问题,但是在我的情况下,该组件中的方法与仅需要一个类的方法存在少量冲突:

headerColorChange() {
    const { classes, color, changeColorOnScroll } = this.props;
    // ...
    document.body
        .getElementsByTagName("header")[0]
        .classList.add(classes[color]) // classes[color] is a string with spaces (two classes)
    ;
    // ...
}

好的。没什么大不了的。我可以修改该方法并解决问题。

但是当我扩展课程时:

import React from "react";
import Header from "material-kit-pro-react/components/Header/Header.jsx";

export default class extends Header {
    constructor(props) {
        super(props);
        this.headerColorChange = this.headerColorChange.bind(this);
    }
    headerColorChange() {
        const { classes, color, changeColorOnScroll } = this.props
        console.log(classes[color])
    }
}

我收到与withStyles相关的错误:

withStyles.js:125 Uncaught TypeError: Cannot read property '64a55d578f856d258dc345b094a2a2b3' of undefined
    at ProxyComponent.WithStyles (withStyles.js:125)
    at new _default (Header.jsx:11)
    at new WithStyles(Header) (eval at ./node_modules/react-hot-loader/dist/react-hot-loader.development.js (http://localhost:8080/bundle.js:137520:54), <anonymous>:5:7)

现在我迷路了。

自定义已样式化的组件的最佳方法是什么?

如何扩展和覆盖HoC(withStyles)的构造函数?

编辑以提供更好和最小的示例:

我有一个无法修改的组件,因为它是由图书馆提供的:

./Component.jsx

import React from "react";
import withStyles from "@material-ui/core/styles/withStyles";

class Component extends React.Component {
    constructor(props) {
        super(props);
        this.headerColorChange = this.headerColorChange.bind(this);
    }

    componentDidMount() {
        window.addEventListener("scroll", this.headerColorChange);
    }

    headerColorChange() {
        const { classes } = this.props;

        // THIS FAILS IF classes.primary IS NOT A VALID CLASS NAME
        document.body.classList.add(classes.primary);
    }

    render() {
        const { classes } = this.props;
        return <div className={classes.primary}>Component</div>
    }
}

export default withStyles(theme => ({
    primary: {
        color: "#000"
    }
}))(Component);

我想自定义组件的原色。直接方法:

./CustomizedComponent.jsx

import React from "react";
import withStyles from "@material-ui/core/styles/withStyles";

import Component from "./Component";

export default withStyles({
    primary: {
        color: "#00f"
    }
})(Component)

好的。的颜色已更改为#0ff。但是随后组件在document.body.classList.add(classes.primary)中失败,因为classes.primary包含两个串联的类名(Component-primary-13 WithStyles-Component--primary-12)。如果允许我修改原始组件,那将没有问题。但是我不能,所以我决定扩展它并覆盖headerColorChange:

./CustomizedComponent.jsx

import React from "react";
import withStyles from "@material-ui/core/styles/withStyles";

import Component from "./Component";

class MyComponent extends Component {
    constructor(props) {
        super(props)
        this.headerColorChange = this.headerColorChange.bind(this);
    }

    headerColorChange() {
    }
}

export default withStyles({
    primary: {
        color: "#00f"
    }
})(MyComponent)

但是然后我得到了错误:

withStyles.js:125 Uncaught TypeError: Cannot read property '64a55d578f856d258dc345b094a2a2b3' of undefined
    at ProxyComponent.WithStyles (withStyles.js:125)
    at new MyComponent (Header.jsx:7)
    at new WithStyles(Component) (eval at ./node_modules/react-hot-loader/dist/react-hot-loader.development.js (http://0.0.0.0:8080/bundle.js:133579:54), <anonymous>:5:7)
    at constructClassInstance (react-dom.development.js:12484)
    at updateClassComponent (react-dom.development.js:14255)

问题是:

是否可以完全覆盖组件的样式,这样我只能得到一个类名?

如何将withStyles函数返回的组件扩展为高阶组件?

0 个答案:

没有答案