Создание тематического компонента React с JSS

У меня проблемы с соблюдением документации о том, как заставить это работать

У меня есть компонент, в котором создано несколько стилей, по большей части все эти стили будут применяться везде, где отображается этот компонент, но иногда в зависимости от того, на какую страницу направлено приложение, я хочу изменить общую высоту компонента на эти страницы. Я подумал, что могу просто сделать это, добавив какие-то новые реквизиты для высоты, чтобы следовать более тематическому подходу. Как мне заставить это работать с моей текущей настройкой?

Файл стилей

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>

И это тема, которую я на самом деле вижу в материальной теме, а не в своей собственной, объединенной где-либо в ней.


person Jordan    schedule 05.03.2018    source источник


Ответы (2)


Вот как я заставил это работать

Сначала я переместил компонент без состояния в новый файл

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 для создания нового экземпляра поставщика темы. Затем необходимо обернуть фактический код компонента, поэтому я решил создать по существу «контейнерный» компонент и фактический компонент как отдельные части, чтобы я мог сохранить логику отдельно. Кроме того, это по-прежнему позволяет мне сделать один без гражданства, а другой - нет, если я так выберу.

person Jordan    schedule 05.03.2018

Вы путаете MuiThemeProvider и объект из react-jss.

person Oleg Isonen    schedule 05.03.2018
comment
Я хочу, чтобы все приложение использовало MuiTheme, а затем мой пользовательский компонент также имел собственную тему с унаследованными стилями от MuiTheme. Нужно ли мне не использовать экспорт из react-jss, если я хочу также использовать MuiTheme? - person Jordan; 05.03.2018