Настройка темы потеряна при рендеринге в строку на клиенте

Я использую material-ui-next и настроил тему, чтобы использовать мои цветовые стили и собственный шрифт. например. Подзаголовок типографики

Теперь я пытаюсь преобразовать компонент в строку для использования в информационном окне карт Google. Тема material-ui по умолчанию доступна в объекте обратного вызова styles, переданном в withStyles, но ни одна из моих настроек недоступна для аргумента theme в обратном вызове styles и не применяется. В остальном визуализированная строка отображается правильно (хотя и без событий, которых я ожидал).

Короче говоря, при обычном рендеринге применяются настройки. При рендеринге в строку они этого не делают.

Простым примером может быть компонент, который правильно работает со стилями, но возвращает div вместо целевого компонента ala:

let output = ReactDOMServer.renderToString(component); return <div dangerouslySetInnerHTML={{__html: output}} />

Есть какие-нибудь советы, как передать настройки моей темы в аргумент обратного вызова withStyles theme?


person Blaine Garrett    schedule 25.11.2017    source источник


Ответы (1)


Решением было создать родительский компонент, который отображает целевой компонент как дочерний для ThemeProvider. Обработчиков событий по-прежнему нет (как и ожидалось), но применяются настройки темы.

Вот решение:

MyThemeProvider.js (компонент также можно легко повторно использовать для SSR)

export default function MyThemeProvider({children}) {
  const muiTheme = createMuiTheme({
    typography: {
      fontFamily: '"Bryant", "Helvetica", "Arial", sans-serif',
    },
    palette: {
      primary: customBluePalette,
    },
    // ... 
  });
  return (<MuiThemeProvider theme={muiTheme}>{ children }</MuiThemeProvider>);
}

MapInfoWindowContent.js (здесь он существует только для того, чтобы обернуть VenueRenderer нашим поставщиком тем)

import MyThemeProvider from '../MyThemeProvider';
import VenueRenderer from '../VenueRenderer';
export default function MapInfoWindowContent({resource}) {
  return (<MyThemeProvider><VenueRenderer resource={resource} /></MyThemeProvider>);
}

VenueRenderer (стилизованный класс - также может использоваться независимо от MapInfoWindowContent)

const styles = (theme) => {
    // theme.palette.primary['500'] comes from customBluePalette so the injection worked.
}
// ...
export default withStyles(styles, { withTheme: true })(VenueRenderer);

В каком-то другом компоненте, которому требуется HTML str

import ReactDOMServer from 'react-dom/server'
import MapInfoWindowContent from '../MapInfoWindowContent';

let infoWindowComponent = (<MapInfoWindowContent resource={ ... }/>);
let output = ReactDOMServer.renderToString(infoWindowComponent);
// output will have correctly injected classNames that contain customizations
person Blaine Garrett    schedule 26.11.2017