Изменить css компонента реакции на основе реквизита с помощью css-модулей

У меня есть следующее:

className={`${this.props.match.params.id}.alert`}

/* desired output = `className="style_alert__3TLGs"` */
/* instead output = `className="style.alert"` */

Если я жестко запрограммирую className (например, {style.alert}), я получу желаемый результат. Кажется, что результат представляет собой строку и не обрабатывается пакетом css-module (возможно, потому, что он отображается после?), Как я могу изменить это, чтобы className обрабатывался css-модулем и связывался, как я намереваюсь?

справочные документы: css-modules


person John107    schedule 14.01.2020    source источник
comment
Я не понимаю, что ты хочешь сделать. Почему вы отправляете идентификатор в класс? ${this.props.match.params.id}.alert станет чем-то вроде className="48.alert".   -  person Valentin Duboscq    schedule 14.01.2020
comment
Когда вы используете интерполяцию строк, результатом будет строка, это не является неожиданным. Каково значение this.props.match.params.id?   -  person Drew Reese    schedule 14.01.2020
comment
@ValentinDuboscq - Очень просто, идентификатор представляет модуль CSS, который я хочу вызвать для повторно используемого компонента, и стиль меняется в зависимости от того, какой идентификатор используется. Затем это обрабатывается пакетом css-modules. Вот очень простой пример: create-react-app. dev/docs/adding-a-css-modules-stylesheet   -  person John107    schedule 14.01.2020
comment
@DrewReese значение в приведенном выше примере — это стиль, я понимаю, что это не неожиданно, но мой вопрос в том, как я могу добиться желаемого результата с помощью реквизита, который может каждый раз меняться, и правильно ли он обрабатывается пакетом css-modules?   -  person John107    schedule 14.01.2020
comment
Вы просто пытаетесь динамически назначить имя класса из какого-то объекта стилей, скажем, что-то вроде className={styles[this.props.match.params.id].alert}?   -  person Drew Reese    schedule 14.01.2020
comment
@DrewReese Я думаю, он хочет динамически импортировать различные модули CSS на основе идентификатора. Может быть, я не совсем понимаю, но я не думаю, что это право делать то, что ты хочешь делать.   -  person Valentin Duboscq    schedule 14.01.2020
comment
@ValentinDuboscq Ах, да, это имеет смысл.   -  person Drew Reese    schedule 14.01.2020
comment
Ага, @ValentinDuboscq понял! Я пытаюсь динамически изменить css на основе идентификатора. Я просто не уверен в лучшем подходе и ищу некоторые предложения.   -  person John107    schedule 14.01.2020


Ответы (1)


Вариант 1. Импортируйте все модули стилей, которые, как вы знаете, будете использовать.

Создайте карту ваших импортированных объектов «стиля», которые будут указаны с помощью ids, переданных в реквизите. Просто нужно убедиться, что все объекты «стиля» имеют одинаковые свойства CSS, такие как «оповещение», и, конечно же, используйте защитный шаблон на пути объекта к параметру id, чтобы не было доступа «неопределенный из».

import styles1 from "....";
import styles2 from "....";
...

const stylesMap = {
  style1Id: styles1,
  style2Id: styles2,
  ...
};

...

className={stylesMap[this.props.match.params.id].alert}

Плюсы: загружать все необходимые CSS-модули и, вероятно, немного проще рассуждать и отлаживать.

Минусы: использует больше ресурсов

Вариант 2. Используйте динамический импорт

Создайте асинхронную функцию для «выборки» требуемого модуля CSS и используйте функцию жизненного цикла компонента или хук эффекта для обновления ссылки на объект стиля.

const loadStyle = async (...params) => {
  try {
    const styleObject = await import(...path and module name from params);
    // setState or useState setter to set style object
  } catch {
    // set a fallback style object
  }
}
...

componentDidMount() {
  // check props.match.params.id
  // gather up other CSS module path details
  // trigger dynamic CSS module load
  loadStyle(... CSS module path detials);
}
**OR**
useEffect(() => {
  // check props.match.params.id
  // gather up other CSS module path details
  // trigger dynamic CSS module load
  loadStyle(... CSS module path detials);
}, [props.match.params.id, ...any other dependencies]);

...

className={stylesMap[<this.>state.styleObject].alert}

Плюсы: Меньший размер/меньшее использование ресурсов.

Минусы: возможно, большая задержка при рендеринге, поскольку ресурсы не извлекаются заранее.

Примечание. Также все зависит от использования вашего приложения, потребностей и требований. Например, если это связанное приложение (например, Cordova/PhoneGap, Electron и т. д.), то более разумно включить в него все необходимые ресурсы.

person Drew Reese    schedule 14.01.2020
comment
Удивительно! Не знал, что это возможно - спасибо, что поделились своей мудростью! - person John107; 14.01.2020
comment
Возможно, лучшим подходом будет использование динамического импорта, поскольку вам не нужно импортировать все ваши файлы. - person Valentin Duboscq; 14.01.2020
comment
@ValentinDuboscq Я включил идею использования динамического импорта, спасибо. Не стесняйтесь указывать на любые недостатки/ошибки. - person Drew Reese; 14.01.2020