在withStyles中使用defaultProps

时间:2019-09-11 16:47:42

标签: javascript reactjs material-ui

我正在使用material-ui withStylers和defaultProps创建一个组件,但是当我尝试使用组件的props时,在样式对象中,我从不获取默认props的值,仅当它获得值时被传递给组件。 我的组件结构是这样的:

import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core";

const styles = theme => ({
    ClassTest: {
        anyAttr: props => console.log(props) 
    }
});

const Test = ({classes}) => {
    return (
        <span className={classes.ClassTest}/>
    );
};

Test.defaultProps = {
    val2: "hey"
};

Test.propTypes = {
    val1: PropTypes.bool.isRequired,
    val2: PropTypes.string,
};

export default withStyles(styles, { withTheme: true })(Test);

我这样使用

<Test val1="Hello">

我希望控制台日志显示如下内容:

{
  classes: {...},
  val1: "Hello",
  val2: "hey"
}

但是,相反,我得到了这个

{
  classes: {...},
  val1: "Hello"
}

如果我这样调用该组件:

<Test val1="Hello" val2="hey">

我知道了:

{
  classes: {...},
  val1: "Hello",
  val2: "hey"
}

因此,考虑defaultProps,styles对象不应该提供props的值吗?我做对了还是错过了什么?

我正在使用以下版本:

"@material-ui/core": "^4.3.0",
"react": "^16.8.6",

我基于文档的这一部分
https://material-ui.com/styles/basics/#adapting-based-on-props

1 个答案:

答案 0 :(得分:0)

withStylesTest包装在一个高阶组件中,并且对Test的默认道具没有可见性。 withStyles被添加到Test的属性中(注入了classes道具),因此Test的默认道具直到withStyles完成后才能确定它的工作(例如,如果Test具有classes的默认属性,则withStyles提供classes时将不会使用该属性,但是不是withStyles包裹)。

在下面的代码中,我演示了三种不同的方法:

  1. 第一种是您尝试过的方法,因为withStyles无法看到默认道具,因此无法使用。
  2. 第二种方法将默认属性应用于withStyles返回的HOC。
  3. 第三种方法使用makeStyles / useStyles而不是withStyles,这使得仍可以在初始组件而不是HOC上保留默认属性。

在显式指定bgcolor时(橙色),所有这三种方法都可以使用,但是只有方法2和3成功地看到了默认的prop值。

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

const styles = {
  test: {
    backgroundColor: props => props.bgcolor
  }
};

const useStyles = makeStyles(styles);

const ApproachThatDoesNotWork = ({ classes }) => {
  return <div className={classes.test}>ApproachThatDoesNotWork</div>;
};
ApproachThatDoesNotWork.defaultProps = {
  bgcolor: "lightgreen"
};
const StyledApproachThatDoesNotWork = withStyles(styles)(
  ApproachThatDoesNotWork
);

const DefaultPropsOnStyledHOC = ({ classes }) => {
  return <div className={classes.test}>DefaultPropsOnStyledHOC</div>;
};
const StyledDefaultPropsOnStyledHOC = withStyles(styles)(
  DefaultPropsOnStyledHOC
);
StyledDefaultPropsOnStyledHOC.defaultProps = {
  bgcolor: "pink"
};

const MakeStylesAndUseStyles = props => {
  const classes = useStyles(props);
  return <div className={classes.test}>MakeStylesAndUseStyles</div>;
};
MakeStylesAndUseStyles.defaultProps = {
  bgcolor: "lightblue"
};

function App() {
  return (
    <div className="App">
      <StyledApproachThatDoesNotWork />
      <StyledApproachThatDoesNotWork bgcolor="orange" />
      <StyledDefaultPropsOnStyledHOC />
      <StyledDefaultPropsOnStyledHOC bgcolor="orange" />
      <MakeStylesAndUseStyles />
      <MakeStylesAndUseStyles bgcolor="orange" />
    </div>
  );
}

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

Edit styles using defaultProps