Reactjs 使用JSS创建可主题化的react组件

Reactjs 使用JSS创建可主题化的react组件,reactjs,material-ui,jss,Reactjs,Material Ui,Jss,我在遵循文档的过程中遇到了一些问题,无法让它正常工作 我有一个创建了一些样式的组件,大多数情况下,所有这些样式都将应用于该组件渲染的任何位置,但有时根据应用程序路由到的页面,我希望更改这些页面上组件的总体高度。我想我可以通过传递一些新的高度道具来实现这一点,采用一种更加以主题为中心的方法。如何使其与当前设置配合使用 样式文件 const styles = theme => ({ root: { backgroundSize: 'cover', padding: '25p

我在遵循文档的过程中遇到了一些问题,无法让它正常工作

我有一个创建了一些样式的组件,大多数情况下,所有这些样式都将应用于该组件渲染的任何位置,但有时根据应用程序路由到的页面,我希望更改这些页面上组件的总体高度。我想我可以通过传递一些新的高度道具来实现这一点,采用一种更加以主题为中心的方法。如何使其与当前设置配合使用

样式文件

const styles = theme => ({
  root: {
    backgroundSize: 'cover',
    padding: '25px 20px',
    boxSizing: 'border-box',
    backgroundPosition: '50% 0',
    backgroundColor: 'rgba(40,70,94,.7)',
    backgroundBlendMode: 'multiply',
    ...theme.root
  }
});

export default styles;
组件文件

import React from 'react';
import styles from './EventTop.styles';
import injectSheet, { ThemeProvider } from 'react-jss';

const EventTop = (props) => (
  <ThemeProvider theme={props.theme}>
    <aside className={props.classes.root} style={{ backgroundImage: `url(${props.event.event_logo})` }}>
      <div className="wrapper">
        <div className="event-info">
          <span className="event-time">
            7:00 PM
          </span>
          <span className="event-date">
            27 Jun 2020
          </span>
          <span className="event-end-time">
            Ends at 10:00 PM
          </span>
          <span className="event-title">
            Bidr Gala
          </span>
          <span className="event-attire">
            Cocktail Attire
          </span>
        </div>
      </div>
    </aside>
  </ThemeProvider>
);

export default injectSheet(styles)(EventTop);

这就是主题,我实际上看到的是材料主题,而不是我自己的主题。你把MuiThemeProvider和react jss的主题搞混了。

下面是我如何做到这一点的

首先,我将无状态组件移动到一个新文件中

EventTop.component.jsx

import React from 'react';
import Moment from 'react-moment';
import styles from './EventTop.styles';

import themableWrapper from '../Themable';

const EventTopComponent = (props) => (
  <aside className={props.classes.root} style={{ backgroundImage: `url(${props.event.event_logo})` }}>
    <div className="wrapper">
      <div className={props.classes.eventInfo}>
        <span className={props.classes.eventTime}>
          <Moment parse="HH:mm:ss" format="h:mm A">{props.event.start_time}</Moment>
        </span>
        <span className={props.classes.eventDate}>
          <Moment parse="YYYY-MM-DD" format="D MMM YYYY">{props.event.event_date}</Moment>
        </span>
        <span className={props.classes.eventEndTime}>
          Ends at <Moment parse="HH:mm:ss" format="h:mm A">{props.event.end_time}</Moment>
        </span>
        <span className={props.classes.eventTitle}>
          {props.event.auction_title}
        </span>
        <span className={props.classes.eventAttire}>
          {props.event.attire}
        </span>
      </div>
    </div>
  </aside>
);

export default themableWrapper(styles)(EventTopComponent);
在新的主题表文件中,我有一些导出设置

import injectSheet, { createTheming } from 'react-jss';

export const theming = createTheming('__NEW_THEME_NAMESPACE__');
export const { ThemeProvider: Themable } = theming;

export default (styles) => injectSheet(styles, { theming });
然后在样式生成器中,我可以使用类似于
lodash
的方法将传入的主题与默认样式设置合并

EventTop.styles.js

import { merge } from 'lodash';

const styles = theme => {
  return merge({
    root: {
      backgroundSize: 'cover',
      padding: '25px 20px',
      boxSizing: 'border-box',
      backgroundPosition: '50% 0',
      backgroundColor: 'rgba(40,70,94,.7)',
      backgroundBlendMode: 'multiply',
    },
    eventInfo: {
      flexGrow: '1',
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'flex-end',
      textAlign: 'left',
      paddingTop: '20px',
      fontWeight: '700',
      color: 'white'
    },
    eventTime: {
      fontSize: '55px'
    },
    eventDate: {
      fontSize: '43px'
    },
    eventEndTime: {
      fontSize: '30px'
    },
    eventTitle: {
      fontSize: '70px'
    },
    eventAttire: {
      fontSize: '30px'
    }
  }, theme);
};

export default styles;

为了使用
MuiThemeProvider
包装整个应用程序,我必须设置一个新的名称空间,然后使用
createTheme
创建一个新的主题提供程序实例。这就需要包装实际的组件代码,这就是为什么我选择创建一个“容器”组件和实际组件作为单独的部分,这样我就可以保持逻辑的独立性。另外,这仍然允许我将其中一个设置为无状态,而另一个设置为非无状态,如果我选择的话

我希望整个应用程序都使用
MuiTheme
,然后我的自定义组件也有自己的主题,带有继承自
MuiTheme
的样式。如果我还想使用
MuiTheme
,我是否需要不使用来自
react jss
的导出?
import React from 'react';
import EventTopComponent from './EventTop.component';

import { Themable } from '../Themable';

const EventTop = ({ theme, ...rest }) => (
  <Themable theme={theme}>
    <EventTopComponent {...rest} />
  </Themable>
);

export default EventTop;
import injectSheet, { createTheming } from 'react-jss';

export const theming = createTheming('__NEW_THEME_NAMESPACE__');
export const { ThemeProvider: Themable } = theming;

export default (styles) => injectSheet(styles, { theming });
import { merge } from 'lodash';

const styles = theme => {
  return merge({
    root: {
      backgroundSize: 'cover',
      padding: '25px 20px',
      boxSizing: 'border-box',
      backgroundPosition: '50% 0',
      backgroundColor: 'rgba(40,70,94,.7)',
      backgroundBlendMode: 'multiply',
    },
    eventInfo: {
      flexGrow: '1',
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'flex-end',
      textAlign: 'left',
      paddingTop: '20px',
      fontWeight: '700',
      color: 'white'
    },
    eventTime: {
      fontSize: '55px'
    },
    eventDate: {
      fontSize: '43px'
    },
    eventEndTime: {
      fontSize: '30px'
    },
    eventTitle: {
      fontSize: '70px'
    },
    eventAttire: {
      fontSize: '30px'
    }
  }, theme);
};

export default styles;