Если вы оказались в ситуации, когда вам нужно сразу стилизовать некоторую группу компонентов React, но вы находитесь в ситуации, когда производительность вашего веб-сайта снижается, то это может быть вашим ответом.

TLDR: ссылка на пример проекта

Пример записи проекта: сетка из 40 000 ячеек (большинство ячеек за пределами экрана). с обновлениями CSS, применяемыми при наведении курсора мыши через ~ 1 мс. Все ячейки с одинаковым номером получают изменение CSS. Выполнение этого путем обновления чего-либо в состоянии реагирующего компонента занимает как минимум в 1000 раз больше времени.

Предпосылка: у вас есть DOM с сотнями или даже многими тысячами компонентов, и вы хотите стилизовать некоторые из них на основе некоторого значения.

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

Решение. Не изменяйте состояние ни одного компонента! Назначайте классы на основе желаемой группировки, и когда вы хотите изменить некоторые из них, вы обновляете таблицу стилей документа, чтобы ориентироваться на эти классы, когда захотите.

Вот шаги, которые нужно предпринять (пример в реакции, но это может легко применяться в более широком смысле).

1. Применение стилей к группе компонентов

Для компонента, который сильно дублируется и нуждается в стилизации:

Мой пример — очень большая таблица с тысячами отдельных ячеек. Каждая ячейка имеет свойство «cellValue». Это назначается случайным образом как способ дать разным ячейкам общее свойство. Я делаю это в ответ в три шага

  1. Создайте ссылку в конструкторе компонента
constructor() {
    super();
    this.cellRef = React.createRef()
}

2. Назначьте ссылку компоненту, на который я хочу настроить таргетинг

<div ref={this.cellRef} /div>

3. Назначьте класс в componentDidMount. (весь этот процесс может быть выполним без ref и просто с использованием className, но у меня были проблемы с этим).

componentDidMount() {
    const { cellValue } = this.props;
    this.cellRef.current.classList.add(`single-cell-${cellValue}`)
}

2. Настройка родительского компонента

Для компонента, содержащего все дочерние компоненты, которые действительно необходимо изменить:

Родитель должен создать функцию, которая при запуске вызывает обновление CSS. Эта функция должна быть передана в качестве реквизита дочернему компоненту из предыдущего шага. (обратите внимание, что имя класса single-cell-${whatever} определяется из дочернего компонента)

updateStyleSheet(cellValue) {
    for(i=0; i<sheet.rules.length; i++){
        if(sheet.rules[i].cssText.includes('single-cell')){
        sheet.deleteRule(i);
        }
    }
    // No judging for !important for a proof of concept
    sheet.insertRule(`.single-cell-${cellValue} { background-color: red !important}`, sheet.rules.length);
    }

Что происходит: в моем примере я просто хочу, чтобы ячейки с тем же значением ячейки, что и передаваемое, были окрашены в красный цвет. Таким образом, цикл for очищает все предыдущие правила по этому поводу. InsertRule добавляет новое правило и применяет его ко всему документу. Ни одно состояние компонента не было изменено, и CSS применяется ко всему очень быстро.

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