首页 > 解决方案 > 当使用 withStyles api 时,如何允许通过 props 自定义 React 组件的样式?

问题描述

我正在为我们的 React(使用 MaterialUI)应用程序编写一些简单的可重用组件。

问题是,我想允许这个相同的可重用组件的不同样式,由消费组件通过道具定制。

这是一些代码:

import { withStyles } from '@material-ui/core';

const styles = theme => ({
image: {
    maxHeight: '200px'
}
});

render() {
        const classes = this.props.classes
        return (
            <div>
                 ...
                 <img className={classes.image} src={this.state.filePreviewSrc} alt="" />
                 ...
            </div>
        );
    }

比方说,我想让程序员自定义 classes.image 的外观。可以以某种方式覆盖硬编码的图像类吗?

使用 withStyles api 甚至是正确的方法,用于创建外观可以由消费组件/程序员自定义的组件?

标签: cssreactjsmaterial-ui

解决方案


支持样式自定义的主要方法有以下三种:

  1. 在您的风格中利用道具
  2. 利用 props 来确定是否应该应用某些类
  3. 通过进行自定义withStyles

对于选项 3,包装组件的样式将与原始样式合并,但包装组件的 CSS 类将在后面出现<head>,并将胜过原始样式。

下面是一个显示所有三种方法的示例:

可重用组件.js

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

const styles = {
  root: props => ({
    backgroundColor: props.rootBackgroundColor
      ? props.rootBackgroundColor
      : "green"
  }),
  inner: props => ({
    backgroundColor: props.innerBackgroundColor
      ? props.innerBackgroundColor
      : "red"
  })
};

const ReusableComponent = ({ classes, children, suppressInnerDiv = false }) => {
  return (
    <div className={classes.root}>
      Outer div
      {suppressInnerDiv && <div>{children}</div>}
      {!suppressInnerDiv && (
        <div className={classes.inner}>
          Inner div
          <div>{children}</div>
        </div>
      )}
    </div>
  );
};
export default withStyles(styles)(ReusableComponent);

index.js

import React from "react";
import ReactDOM from "react-dom";
import { withStyles } from "@material-ui/core/styles";

import ReusableComponent from "./ReusableComponent";

const styles1 = theme => ({
  root: {
    backgroundColor: "lightblue",
    margin: theme.spacing(2)
  },
  inner: {
    minHeight: 100,
    backgroundColor: "yellow"
  }
});
const Customization1 = withStyles(styles1)(ReusableComponent);

const styles2 = {
  inner: {
    backgroundColor: "purple",
    color: "white"
  }
};
const Customization2 = withStyles(styles2)(ReusableComponent);

function App() {
  return (
    <div className="App">
      <ReusableComponent>Not customized</ReusableComponent>
      <Customization1>Customization 1 via withStyles</Customization1>
      <Customization2>Customization 2 via withStyles</Customization2>
      <ReusableComponent rootBackgroundColor="lightgrey" suppressInnerDiv>
        Customization via props
      </ReusableComponent>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

编辑样式可重用组件


推荐阅读