Как я могу настроить приложение create-реакции-приложение для экспорта CSS в два разных файла - PullRequest
0 голосов
/ 10 ноября 2018

Я работаю над проектом, который позволит пользователю динамически менять темы, и использует внутреннюю часть реактивного ремешка и стилизованные компоненты. Мы хотим настроить все переменные через SASS, который работает нормально. Чтобы сделать эти переменные доступными для стилевых компонентов, мы использовали sass-extract-loader для создания объектов темы.

Все это прекрасно работает, когда мы статически выбираем одну из тем, но я не смог заставить ее работать надежно динамически. У меня есть два вопроса:

1) В разработке нормально работает переключение темы один раз . Если я изменю это снова, мои не стилизованные компоненты (то есть, необработанные компонентыactstrap) будут оформлены со второй темой. Я считаю, что это потому, что вторая тема загружает и переопределяет оригинальный CSS. 2) В производственной среде я получаю ту же смесь, что и # 1 по умолчанию (т. Е. Поскольку все CSS-файлы объединяются в один пакет, компонентыactstrap стилизуются одним способом, в то время как стилевые компоненты «уважают» тему) .

Я считаю, что лучший вариант для нас - это иметь темы в двух отдельных файлах CSS и переключать «альтернативные» ссылки на них. Я просто не знаю, как настроить CRA, чтобы не помещать весь CSS в один основной пакет, и позвольте мне вручную добавлять ссылки на альтернативные таблицы стилей. Если я смогу разделить их на отдельные файлы, я считаю, что могу просто добавить теги и динамически поменять свойство rel = "alternate".

Вполне возможно, есть лучшие способы сделать это. Насколько я понимаю, самый простой способ управления темами Bootstrap - через переменные SASS, и я хотел бы убедиться, что эти переменные не нужно переопределять при их использовании в styled-components.

1 Ответ

0 голосов
/ 10 ноября 2018

Если вы хотите применять стили условно, вы можете импортировать свои таблицы стилей в файл index.js и сделать его доступным для всех ваших компонентов через API контекста. Прежде всего мы импортируем файлы CSS в index.js.

import themeA from './css/themeA.css';
import themeB from './css/themeB.css';

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

Используя модули CSS, вы избавляетесь от необходимости выбора элементов. Возможно, вы захотите прочитать эту статью, если вы не знакомы с модулями CSS: https://javascriptplayground.com/css-modules-webpack-react/

Если вам все еще нужно применить селекторы элементов в одной теме, вы можете сделать это, но они также будут применены в другой теме.

 import './css/default.css';

Этот пример ниже является модифицированной версией из документации React: https://reactjs.org/docs/context.html

В этом примере мы рисуем кнопку, которая меняет глобальную тему, когда это его щелкнуло. В этом примере есть три части, которые имеют решающее значение чтобы понять, если вы хотите использовать React его контекстный API.

1. Создание контекста. Создание контекста выполняется путем присвоения возвращаемого значения React.createContext(yourValue) переменной. Затем эту переменную можно использовать для использования компонента Provider или Consumer внутри компонентов React.

const ThemeContext = React.createContext();

2. Предоставление значения путем передачи его компоненту провайдера в виде проп. Теперь ваше значение доступно для всех ваших компонентов.

class App extends React.Component {
  swapTheme() {
    this.setState({ withThemeA: !this.state.withThemeA });
  }
  render() {
    const theme = this.state.withThemeA ? themeA : themeB;
    return (
      <ThemeContext.Provider value={theme}>
        <ThemedButton onClick={this.swapTheme} />
      </ThemeContext.Provider>
    );
  }
}

3. Прослушивание обновлений с использованием компонента Consumer. Чтобы прослушать изменения, вам нужно использовать компонент Consumer. Переданная функция получает тему в качестве аргумента, поэтому ее можно назначить реквизиту className элемента кнопки.

class ThemedButton extends React.Component {
  render() {
    return <ThemeContext.Consumer>
      {theme => <button className={theme.Button}}>click me</button>}
    </ThemeContext.Consumer>;
  }
}
...