【问题标题】:Reference to theme's primary color instead of a specific color in MUI引用主题的原色而不是 MUI 中的特定颜色
【发布时间】:2017-09-03 00:13:30
【问题描述】:

使用 ReactJS 和 MUI,我有一个项目,我在其中更改了主题颜色。

const newTheme = getMuiTheme({
    fontFamily: 'Roboto, sans-serif',
    palette: {
        primary1Color: cyan500,
        primary2Color: cyan700,
        primary3Color: grey400,
        accent1Color: amberA400,
        accent2Color: grey100,
        accent3Color: grey500,
        textColor: darkBlack,
        alternateTextColor: white,
        canvasColor: white,
        borderColor: grey300,
        disabledColor: fade(darkBlack, 0.3),
        pickerHeaderColor: cyan500,
        clockCircleColor: fade(darkBlack, 0.07),
        shadowColor: fullBlack,
    },
});

  // App class
  render() {
    return(
        <ThemeProvider theme={newTheme}>
            <Project />
        </ThemeProvider>
    )
  }

一切都按预期进行。某些组件,例如按钮,可以根据主要道具设置颜色。但是,我有一个使用需要原色的图标的组件。我可以直接导入颜色并设置:

import React from 'react';
import ActionLock from 'material-ui/svg-icons/action/lock';
import {cyan500} from 'material-ui/styles/colors';

export default class LockIcon extends React.Component {
    render() {
        return(
            <ActionLock color={cyan500} />
        )
    }
}

有没有办法引用主题的原色,而不是单独设置每个组件的颜色?比如:

import React from 'react';
import ActionLock from 'material-ui/svg-icons/action/lock';
import {primary1Color} from 'somewhere';

export default class LockIcon extends React.Component {
    render() {
        return(
            <ActionLock color={primary1Color} />
        )
    }
}

【问题讨论】:

标签: reactjs material-ui


【解决方案1】:

是的,你有! 使用 muiThemeable..

import muiThemeable from 'material-ui/styles/muiThemeable';
class LockIcon extends React.Component {
    render() {
        return(
            <ActionLock color={this.props.muiTheme.palette.primary1Color} />
        )
    }
}
        export default muiThemeable()(LockIcon)

from material-ui docs

【讨论】:

    【解决方案2】:

    使用 withTheme 组件在material-ui v1.0.0(目前为测试版)中添加如何访问主题颜色。
    还要检查以下Example

    import React, {Component} from 'react';
    import { withTheme } from 'material-ui/styles';
    
    class WithThemeExample extends Component {
        render() {
            const { theme } = props;
            const {primary, secondary} = theme.palette.text;
    
            return (
                <div>
                    <div style={{color: primary}}>Hi in Primary color</div>
                    <div style={{color: secondary}}>Bye in Secondary color</div>
                </div>
            );
        }
    }
    
    export default withTheme()(WithThemeExample);
    

    【讨论】:

    • 道具从何而来?
    • “withTheme”组件正在将颜色注入“WithThemeExample”组件
    • withTheme 需要一个函数,而不是 class。原帖暗示在类内实现。
    【解决方案3】:

    好的,如果您使用的 material-ui 版本大于 4,那么上述解决方案可能不适合您。按照下面的代码

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

    参考:https://material-ui.com/styles/advanced/

    【讨论】:

      【解决方案4】:

      如果您使用 React v16.8.0 和 Material-UI v3.5.0 或更高版本,您可以使用 useTheme() 挂钩:

      import { useTheme } from '@material-ui/core/styles';
      
      function LockIcon = () => {
        const theme = useTheme();
      
        return (
          <ActionLock color={theme.palette.primary1Color} />
      }
      

      【讨论】:

      • @mui/material > 5.1.1中仍然使用这个钩子。但是,调色板的形状发生了一些变化。以theme.palette.main.info 为例。
      【解决方案5】:

      有了 react 钩子,现在你不需要在 withTheme 中扭曲组件,只需使用 useTheme

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

      【讨论】:

        【解决方案6】:

        如果您使用system properties,您可以将Palette 对象的字符串路径定义为颜色值,如下所示:

        <Box sx={{ color: "primary.main" }}>primary.main</Box>
        <Box sx={{ color: "secondary.main" }}>secondary.main</Box>
        <Box sx={{ color: "error.main" }}>error.main</Box>
        <Box sx={{ color: "warning.main" }}>warning.main</Box>
        <Box sx={{ color: "info.main" }}>info.main</Box>
        <Box sx={{ color: "success.main" }}>success.main</Box>
        <Box sx={{ color: "text.primary" }}>text.primary</Box>
        <Box sx={{ color: "text.secondary" }}>text.secondary</Box>
        <Box sx={{ color: "text.disabled" }}>text.disabled</Box>
        

        以上同:

        <Box sx={{ color: theme => theme.palette.primary.main }}>primary.main</Box>
        <Box sx={{ color: theme => theme.palette.secondary.main }}>secondary.main</Box>
        <Box sx={{ color: theme => theme.palette.error.main }}>error.main</Box>
        <Box sx={{ color: theme => theme.palette.warning.main }}>warning.main</Box>
        <Box sx={{ color: theme => theme.palette.info.main }}>info.main</Box>
        <Box sx={{ color: theme => theme.palette.success.main }}>success.main</Box>
        <Box sx={{ color: theme => theme.palette.text.primary }}>text.primary</Box>
        <Box sx={{ color: theme => theme.palette.text.secondary }}>text.secondary</Box>
        <Box sx={{ color: theme => theme.palette.text.disabled }}>text.disabled</Box>
        

        使用回调的示例更冗长但类型安全,只有字符串的较短示例在原型设计时更快更好,但您可能希望将字符串存储在常量中以防止任何拼写错误并帮助 IDE更好地重构你的代码。

        现场演示

        【讨论】:

        • upvote,因为你的答案是 mui 5(目前是 beta)的解决方案,干杯!
        • @Chiu MUI v5 发布now
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-22
        • 1970-01-01
        • 2010-09-18
        • 2018-05-28
        • 2023-02-10
        相关资源
        最近更新 更多