Могут ли стили компонентов быть ограничены вместо встроенных, чтобы предотвратить перезапись несколькими приложениями React на одной странице?

#reactjs #material-ui

#reactjs #материал-пользовательский интерфейс

Вопрос:

У меня есть приложение с html:

 <div id="react-root-navbar"></div>
<div id="react-root-body"></div>
 

и соответствующие компоненты React, которые вызывают React.DOM.render каждый div.

Оба компонента React используют компоненты пользовательского интерфейса Material. Таким образом, для каждого компонента вводится набор встроенных стилей.

Проблема в том, что все стили для второго компонента будут располагаться дальше в HTML, чем для первого компонента, поэтому эти правила CSS будут иметь более высокий приоритет. Это прерывает предполагаемый каскадный поток и приводит к большому количеству неправильных стилей. Например, .MuiAppBar-colorPrimary отменяется .MuiPaper-root :

скриншот прерванного каскадирования

Я знаю, что идеальным решением было бы разместить все компоненты в одном приложении React и в первую очередь предотвратить дублирование импорта. Однако это невозможно с кодовой базой, с которой я работаю, которая использует интерфейс Django, мигрирующий по одной части за раз, чтобы реагировать.

Есть ли какой-либо способ сделать так, чтобы стили, экспортируемые Material UI для каждого компонента, были привязаны конкретно к этому компоненту, чтобы стили не перезаписывали друг друга?

Ответ №1:

В MUI есть компонент StylesProvider , который позволяет настраивать способ добавления стилей. StylesProvider имеет prop generateClassName , которому вы можете передать генератор, чтобы определить, как генерируются имена классов.

Вы можете создать генератор, используя функцию MUI createGenerateClassName , которой вы можете передать опцию disableGlobal добавления простых суффиксов к именам классов, чтобы к каждому приложению применялся CSS с ограниченной областью.

Я уже упаковывал все компоненты MUI в компонент MUIThemeProvider для использования компонента MUI ThemeProvider . Я только что добавил StylesProvider в эту оболочку:

 const generateClassName = createGenerateClassName({
    disableGlobal: true,
});

return (
    <StylesProvider generateClassName={generateClassName}>
        <ThemeProvider theme={theme}>
            {props.children}
        </ThemeProvider>
    </StylesProvider>
)