【问题标题】:Using defaultProps with withStyles将 defaultProps 与 withStyles 一起使用
【发布时间】:2019-09-11 16:47:42
【问题描述】:

我正在使用 Material-ui withStylers 和 defaultProps 创建一个组件,但是当我尝试使用该组件的道具时,在样式对象中,我永远不会获得我的默认道具的值,如果它只获取该值传递给组件。 我的组件结构是这样的:

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,样式对象不应该给出道具的值吗?我做得对还是错过了什么?

我正在使用以下版本:

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

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

【问题讨论】:

    标签: javascript reactjs material-ui


    【解决方案1】:

    withStylesTest 包装在一个高阶组件中,并且对Test 的默认属性不可见。 withStyles 正在添加到 Test 的属性(注入 classes 道具),因此在 withStyles 完成其工作之前无法确定 Test 的默认道具(例如,如果 Test 有一个classes 的默认属性,当withStyles 提供classes 时不会被利用,但是当notwithStyles 包裹时可以利用默认值。

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

    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);
    

    【讨论】:

      猜你喜欢
      • 2020-08-22
      • 1970-01-01
      • 1970-01-01
      • 2019-03-06
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 2021-11-30
      • 2019-06-18
      相关资源
      最近更新 更多