简体   繁体   English

从外部 material-ui 组件访问主题

[英]access the theme from outside material-ui component

I have a theme provider using the standard dark theme.我有一个使用标准深色主题的主题提供程序。 I'd like to be able to access the details of this theme from my own custom component, but I cannot figure out how that would be done.我希望能够从我自己的自定义组件访问此主题的详细信息,但我无法弄清楚如何做到这一点。 In the example below, this.props.theme is undefined在下面的例子中, this.props.theme是未定义的

ReactDOM.render(
    <MuiThemeProvider theme={theme}>
        <App/>
    </MuiThemeProvider>, document.getElementById('root')
);

class App extends Component {
    render() {
        const {classes} = this.props;
        return (
            <div className="App">
                <MainMenu/>
                <div className={classes.root}>
                    <Grid container spacing={8}>
                        <Grid item xs>
                            <Chart theme={this.props.theme}/>
                        </Grid>
                    </Grid>
                </div>
            </div>
        );
    }
}

You can also use the useTheme hook!你也可以使用 useTheme 钩子!

import { useTheme } from '@material-ui/styles';

function DeepChild() {
  const theme = useTheme();
  return <span>{`spacing ${theme.spacing}`}</span>;
}

https://material-ui.com/styles/advanced/#accessing-the-theme-in-a-component https://material-ui.com/styles/advanced/#accessing-the-theme-in-a-component

You need to use the HOC (Higher Order Component) provided with material-ui (note I am using the beta version, YMMV).您需要使用 material-ui 提供的 HOC(高阶组件)(注意我使用的是测试版,YMMV)。

Example:例子:

LeftNavigation.jsx LeftNavigation.jsx

import React from 'react';
import PropTypes from 'prop-types';
import Hidden from 'material-ui/Hidden';
import Drawer from 'material-ui/Drawer';
import List from 'material-ui/List';
import Divider from 'material-ui/Divider';

import { withStyles } from 'material-ui/styles';

import { MailFolderListItems, OtherMailFolderListItems } from '../../../components/tileData';

const styles = theme => ({
  docked: {
    height: '100%',
  },
  drawerPaper: {
    width: 250,
    height: '100%',
    [theme.breakpoints.up('md')]: {
      width: theme.drawerWidth,
      position: 'relative',
      height: '100%',
    },
  },
  drawerHeader: theme.mixins.toolbar,
});

class LeftNavigation extends React.Component {
  render() {
    const { classes, theme } = this.props;

    const drawer = (
      <div>
        <div className={classes.drawerHeader} />
        <Divider />
        <List><MailFolderListItems toggle={this.props.handleDrawerToggle} /></List>
        <Divider />
        <List><OtherMailFolderListItems toggle={this.props.handleDrawerToggle} /></List>
      </div>
    );

    return [
      <Hidden mdUp key="mobile">
        <Drawer
          type="temporary"
          anchor={theme.direction === 'rtl' ? 'right' : 'left'}
          open={this.props.mobileOpen}
          classes={{ paper: classes.drawerPaper }}
          onRequestClose={this.props.handleDrawerToggle}
          ModalProps={{ keepMounted: true /* Better open performance on mobile. */ }}
        >
          {drawer}
        </Drawer>
      </Hidden>,
      <Hidden mdDown implementation="css" key="desktop">
        <Drawer
          type="permanent"
          open
          classes={{
            docked: classes.docked,
            paper: classes.drawerPaper,
          }}
        >
          {drawer}
        </Drawer>
      </Hidden>,
    ];
  }
}

LeftNavigation.propTypes = {
  classes: PropTypes.object.isRequired,
  theme: PropTypes.object.isRequired,
  mobileOpen: PropTypes.bool.isRequired,
  handleDrawerToggle: PropTypes.func.isRequired
};

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

The const styles = theme => ({...}) is where you define your styles. const styles = theme => ({...})是您定义样式的地方。

The export default withStyles(styles, { withTheme: true })(LeftNavigation); export default withStyles(styles, { withTheme: true })(LeftNavigation); shows the usage with the higher order component to pass the styles / theme down to your component.显示了使用高阶组件将样式/主题向下传递给您的组件的用法。

I use withTheme: true so that not only my styles, but the theme is passed as well.我使用withTheme: true这样不仅我的风格,而且主题也被传递了。

So for your code, I would do the following:因此,对于您的代码,我将执行以下操作:

import { withStyles } from 'material-ui/styles';

const styles = theme => ({
  root: {
    height: '100%'
  }
})

class App extends Component {
    render() {
        const {classes} = this.props;
        return (
            <div className="App">
                <MainMenu/>
                <div className={classes.root}>
                    <Grid container spacing={8}>
                        <Grid item xs>
                            <Chart theme={this.props.theme}/>
                        </Grid>
                    </Grid>
                </div>
            </div>
        );
    }
}

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

And for people using Typesctipt and class components, you'll also need to add:对于使用 Typesctipt 和类组件的人,您还需要添加:

export interface MyComponentNameProps extends WithStyles<typeof styles, true> {
// your props here...
theme: Theme
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM