react material ui Рендер компонента в строку ломает CSS
Primary tabs
Ситуация
У нас есть блок, котором работает JS не зависимый от реакта (напр. карта), мы хотим отредндерить какой-то компонент в HTML, чтобы потом показать его во всплывающей подсказке на карте
В коде это может выглядеть как-то так:
import { renderToString } from 'react-dom/server'; // рендерим его let html = renderToString(<MapTooltip />); mapTooltip .setHTML(html) // используем в не-реакт вызове .addTo(map);
Проблема в Material Ui
Если то, что вы рендерите, как-то завязано на использование темы (системы стилизации) Material Ui, то вызов renderToString() на клиенте через систему темизации Матириала добавит новые стили, их имена могу (считайте- сопадут) совпасть с теми, что вы используете в основном приложении, но т.к. мы проводим рендеринг без ThemeProvider, то эти стили будут стилями по-умолчанию, что сломает вашу верстку.
Варианты решения
1. Рендерить используя ThemeProvider
Рендерить используя ThemeProvider, причем передавать нужно ту же тему, что вы создали в основном приложении
Плюсы подхода: используйте все возможности Материала
Минусы подхода: с каждым вызовом renderToString() будет происходить дублирование CSS (дублировать будут все те же стили, но все равно это не очень хорошо) + такой подход может быть затратным по ресурсам
2. Отказать в renderToString() от всех зависимостей от Material Ui
Это более экономный по ресурсам вариант + более изящный.
Как его реализовать:
- В аргументе ( в примере выше то MapTooltip) откажитесь от любых вызовов связанных с работой CSS через Матириал, напр. не вызывайте useStyles()
- Получайте имена классов для MapTooltip (напр. через useStyles()) как пропсы этого компонента MapTooltip, для этого вызовете useStyles() в том компоненте, что делает вызов renderToString() и является обычным реактовским.
Таким образом вы не будете генерировать стили заново на каждый вызов renderToString(), а просто получите имена классов как пропсы-строки и подставите их. Генерация html, таким образом вообще не будет влиять на систему работы с CSS material UI
Ссылки "по теме":
- Похожий пример рендера с ThemeProvider: https://stackoverflow.com/a/47491794
- Просто связанное, для экспериментов с вложениями --Theme nesting with Material UI: https://stackoverflow.com/questions/5694...
- Log in to post comments
- 1686 reads
vedro-compota
Fri, 07/23/2021 - 11:53
Permalink
https://t.me/undfnd
https://t.me/undfnd
_____________
матфак вгу и остальная классика =)