我有一个材料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函数返回的组件扩展为高阶组件?