如何将material-ui的主题对象传递给defaultProps?

How to pass material-ui's theme object to defaultProps?

在 React 中,我有一个功能组件可以验证道具并为任何不需要的道具实现默认道具。我还使用 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;

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

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

在您的顶级组件中,例如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>;
}

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

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