【问题标题】:Creating themeable react component with JSS使用 JSS 创建可主题化的反应组件
【发布时间】:2018-03-05 16:29:05
【问题描述】:

我在遵循有关如何使其工作的文档时遇到了一些麻烦

我有一个创建了一些样式的组件,在大多数情况下,所有这些样式都将应用于呈现该组件的任何位置,但有时取决于应用程序被路由到的页面,我会想要更改整体高度这些页面上的组件。我想我可以通过传递某种新的高度道具来遵循更以主题为中心的方法来做到这一点。我如何让它与我当前的设置一起使用?

样式文件

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

然后当我渲染它时,我画了这样的东西

<EventTop event={this.props.events.currentEvent} theme={{ height: 'calc(100vh - 64px)' }}/>

但是当我尝试通过控制台注销主题时,我看不到主题进入样式生成器。

我安装了Material UI,整个应用程序都包含在MuiThemeProvider

<Provider store={store}>
  <MuiThemeProvider theme={theme}>
    <App>
      <Reboot />
      <AppRouter />
    </App>
  </MuiThemeProvider>
</Provider>

这是我实际看到的主题主题,而不是我自己的主题。

【问题讨论】:

    标签: reactjs material-ui jss


    【解决方案1】:

    这是我如何让它工作的

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

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

    然后在EventTop.jsx 中,我导入无状态组件并返回另一个无状态组件,但这个组件被包装在一个新的主题包装器中

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

    然后在样式生成器中,我可以使用 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 创建一个新的主题提供程序实例。然后,这需要包装实际的组件代码,这就是为什么我选择本质上创建一个“容器”组件和实际组件作为单独的部分,这样我就可以将逻辑分开。另外,如果我愿意,这仍然允许我使一个无国籍,而另一个则不是

    【讨论】:

      【解决方案2】:

      你把 MuiThemeProvider 和 react-jss 的那个混淆了。

      【讨论】:

      • 我希望整个应用程序使用MuiTheme,然后我的自定义组件也有自己的主题,并继承自MuiTheme 的样式。如果我还想使用MuiTheme,我是否需要不使用来自react-jss 的导出?
      猜你喜欢
      • 2019-12-31
      • 1970-01-01
      • 2016-02-29
      • 2017-12-28
      • 2019-06-25
      • 2014-10-02
      • 2019-04-22
      • 2016-12-09
      • 1970-01-01
      相关资源
      最近更新 更多