Классы стилей React + Material-UI из разных компонентов конфликтуют при статическом обслуживании - PullRequest
0 голосов
/ 16 июня 2019

Проблема: стили, применяемые к именам классов, созданным Material-UI / JSS, неправильно изменяются при повторной визуализации компонентов.

Настройка: я работаю с приложением React (созданным с create-react-app), в котором используется jss-стиль Material-UI и серверная часть Rails. Я не уверен, насколько важна часть Rails, так как то же самое происходит, когда я открываю файл build/index.html непосредственно на моем локальном компьютере - серверная часть Rails обрабатывает корневой запрос на обслуживание статических клиентских файлов, как представлено здесь . В любом случае статическая сборка создается с использованием npm run build, который запускается react-scripts build (из create-react-app).

Пример проблемы: у меня есть элемент <img>, которому присваивается className: {classes.logo}. При сборке classes.logo равен "jss3", что соответствует следующему правильному CSS:

.jss3 {
    height: 50px;
    position: relative;
    // [...more]
}

Это выглядит так - компонент <img> находится вверху слева в заголовке приложения.

enter image description here

Я "продолжить как гость", и новые компоненты отображаются. Но обратите внимание на изображение логотипа, которое теперь имеет новый стиль:

enter image description here

Что случилось? Компонент <img> теперь отображает следующий стиль:

.jss3 {
    height: 2em;
    padding: 7px;
    overflow: scroll;
    position: relative;
}

Этот css происходит из совершенно другого стиля объекта из другого компонента:

// FileEntry.js

  fileEntry: {
    position: 'relative',
    padding: '7px',
    height: '2em',
    overflow: 'scroll',
  },

Из журналов я определил, что classes.logo в AppHeader.js и classes.fileEntry из FileList.js имеют имя "jss3". Это объясняет, почему стили изменились - был создан новый компонент (<FileEntry), который переписал стили класса "jss3".

Итак, главный вопрос на данный момент: почему обоим элементам стиля присваивается конфликтующее имя "jss3"? Как я могу избежать этого с помощью статического внешнего приложения? (Проблема также возникает, когда я следую инструкциям из блога выше для развертывания на heroku.) Мне бы очень понравился ответ, который все же позволил мне разместить как клиент, так и серверную часть из одного запущенного экземпляра, как я делаю здесь , но если другой вариант развертывания - лучший ответ, я бы хотел узнать, как + почему.

1 Ответ

0 голосов
/ 18 июня 2019

Проблема связана с использованием двух разных версий генератора имен классов. Много способов сделать это; в моем случае я смешивал более старую версию material-ui/core/styles#withStyles с более новой material-ui/styles#makeStyles, так как я выполнял рефакторинг компонентов класса для использования хуков. Убрав использование старого core/styles#withStyles, я исправил проблему.

Что происходит, если два генератора имен классов не знают друг друга и создают имена классов с простыми индексами (например, jss3). По крайней мере, они делают это для производственных сборок, кажется, что в сборках dev используются более подробные имена классов, основанные на именах компонентов, что объясняет, почему я видел его только при статическом размещении.

Поскольку компонент FileEntry не отображался до входа в систему, имя класса jss3 не создавалось генератором имен второго класса до тех пор, пока не было выполнено действие входа в систему, после чего классу jss3 был присвоен обновленный стиль, и браузер применил его к существующим элементам jss3, как и предполагалось.

Некоторые обходные решения, включающие в себя принудительное использование обоих поставщиков одного и того же Jss-провайдера, но без использования в первую очередь независимых вызовов генераторов имен классов, были более тщательным и хорошо поддерживаемым решением.

Подобные проблемы описаны здесь:

...