【问题标题】:How to pass material-ui's theme object to defaultProps?如何将 material-ui 主题对象传递给 defaultProps?
【发布时间】:2020-04-14 17:30:41
【问题描述】:

在 React 中,我有一个功能组件,用于验证 props 并为任何非必需的 props 实现默认 props。我还使用 mui 的 makeStyles 来获取 theme 对象以将样式应用于我的组件。

我的问题是如何将makeStyles 主题对象传递给defaultProps 以避免硬键控值?

import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles } from '@material-ui/core/styles';


const useStyles = makeStyles(theme => ({
  componentStyle: {
    color: `${theme.palette.light.main}`,  // just like how I'm accessing `theme` here, I'd like to access in `defaultProps`
  },
  componentContainer: ({ backgroundColor }) => {
    return { backgroundColor };
  },
}));


const Example = ({ backgroundColor }) => {
  const classes = useStyles({ backgroundColor });

  return (
    <div className={classes.componentStyle} >
      <div className={classes.componentContainer} /> // use default styling using `theme` if none is provided
    </div>
  )

}


Example.propTypes = {
  backgroundColor: PropTypes.string,
};


Example.defaultProps = {
  backgroundColor: `${theme.palette.light.main}`,  // I want to access `theme` here and do the following. While `backgroundColor: 'white'` will work I want to avoid hard keying values. 
};


export default Example;

编辑:基于@Fraction 提供的解决方案,我将继续前进。

import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles } from '@material-ui/core/styles';


const useStyles = makeStyles(theme => ({
  componentStyle: {
    color: `${theme.palette.light.main}`,
  },
  componentContainer: ({ backgroundColor }) => {
    return { 
      backgroundColor: backgroundColor || `${theme.palette.light.main}`
    };
  },
}));


const Example = ({ backgroundColor }) => {
  const classes = useStyles({ backgroundColor });

  return (
    <div className={classes.componentStyle} >
      <div className={classes.componentContainer} />
    </div>
  )

}


Example.propTypes = {
  backgroundColor: PropTypes.string,
};


Example.defaultProps = {
  backgroundColor: null, 
};


export default Example;

【问题讨论】:

    标签: reactjs material-ui react-props


    【解决方案1】:

    我建议不要将主题作为道具传递,而是使用主题上下文。

    我在我正在开发的所有应用程序中都这样做,它很灵活,也可以防止道具钻孔。

    在您的顶级组件中,例如App.tsx把Material UI主题提供者:

    import { ThemeProvider } from '@material-ui/core/styles';
    import DeepChild from './my_components/DeepChild';
    
    const theme = {
      background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    };
    
    function Theming() {
      return (
        <ThemeProvider theme={theme}>
          <DeepChild />
        </ThemeProvider>
      );
    }
    

    然后,在需要主题的组件中: (根据https://material-ui.com/styles/advanced/#accessing-the-theme-in-a-component):

    import { useTheme } from '@material-ui/core/styles';
    
    function DeepChild() {
      const theme = useTheme();
      return <span>{`spacing ${theme.spacing}`}</span>;
    }
    
    

    【讨论】:

    • 好的,谢谢。我只是在这里躲避一些东西。由于我仍然将backgroundColor 作为道具传递给我的Example 组件,我只是想知道如何在那里解决它。我真的不想在我的defaultProps 中硬编码任何值。我应该提到我没有用这个应用程序实现 TS。我完全赞成使用ThemeProvider,但我将无法在我的defaultProps 中使用useTheme
    【解决方案2】:

    您不需要将makeStyles 的主题对象向下传递给defaultProps,只需使用Logical OR ||backgroundColor 属性设置为theme.palette.light.main,当传递的参数为任何假值时,例如:(0''NaNnullundefined):

    const useStyles = makeStyles(theme => ({
      componentStyle: {
        color: `${theme.palette.light.main}`,  // just like how I'm accessing `theme` here, I'd like to access in `defaultProps`
      },
      componentContainer: ({ backgroundColor }) => ({ 
        backgroundColor: backgroundColor || theme.palette.light.main,
      }),
    }));
    

    【讨论】:

    • 我还没有实现这个,但是为了完成你写的,我说得对吗,通过在参数中为backgroundColor设置一个默认值,它不会被任何值覆盖我已分配给defaultProps。基本上我可以将backgroundColordefaultProps 值设置为null
    • 我已经更新了我的答案,只有当 backgroundColor 参数被评估为任何虚假值时,backgroundColor 属性才会采用 theme.palette.light.main
    猜你喜欢
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    相关资源
    最近更新 更多