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

Контекст React — это простой способ глобального обмена данными, но он может затруднить повторное использование компонентов. В качестве альтернативы вы можете создать компонент кнопки темного режима, который использует хуки useEffect и useState вместо контекста. Он переключит атрибут данных в элементе body, на который могут ориентироваться стили CSS.

Что вам понадобится

Чтобы следовать этому руководству, вам потребуется следующее:

  • Последняя версия Node, установленная на вашем компьютере.
  • Базовое понимание React и Реагировать на хуки.
  • Стартовый проект React. Просто создать приложение React и вы готовы идти.

Создайте компонент кнопки

Компонент кнопки будет отвечать за переключение темы с темной на светлую. В реальном приложении эта кнопка может быть частью компонента Navbar.

instagram viewer

В папке src создайте новый файл с именем Button.js и добавьте следующий код.

импорт { состояние использования } из «реагировать»

экспортдефолтфункцияКнопка() {
const [тема, settheme] = useState("темный")

константа handleToggle = () => {
константа newTheme = тема "легкий"? "темный": "легкий"
установить тему (новая тема)
}
возвращаться (
<>
<кнопка className="темаBtn" onClick={handleToggle}>
{тема "легкий"? <охватывать>темный</span>: <охватывать>легкий</span>}
</button>
</>
)
}

Во-первых, импортируйте хук useState() из React. Вы будете использовать его для отслеживания текущей темы.

В компоненте Button инициализируйте темное состояние. Функция handleToggle() позаботится о функции переключения. Он запускается каждый раз, когда нажимается кнопка.

Этот компонент также переключает текст кнопки при изменении темы.

Чтобы отобразить компонент Button, импортируйте его в App.js.

импорт Кнопка из './Кнопка';
функцияПриложение() {
возвращаться (
<див>
<Кнопка/>
</div>
);
}

экспортдефолт Приложение;

Создайте стили CSS

Прямо сейчас нажатие кнопки не меняет пользовательский интерфейс приложения React. Для этого вам сначала нужно создать стили CSS для темного и светлого режима.

В App.css добавьте следующее.

тело {
--цвет-текст-основной: #131616;
--цвет-текст-вторичный: #ff6b00;
--color-bg-основной: #E6EDEE;
--color-bg-вторичный: #7d86881c;
фон: вар(--color-bg-основной);
цвет: вар(--цвет-текст-первичный);
переход: фон 00,25 слегкость входа;
}
тело [данные-тема ="легкий"] {
--цвет-текст-основной: #131616;
--color-bg-основной: #E6EDEE;
}
тело [данные-тема ="темный"] {
--цвет-текст-основной: #F2F5F7;
--color-bg-основной: #0E141B;
}

Здесь вы определяете стили элемента body, используя атрибуты данных. Существует атрибут данных светлой темы и атрибут данных темной темы. Каждый из них имеет переменные CSS с разными цветами. Использование атрибутов данных CSS позволит вам переключать стили в соответствии с данными. Если пользователь выбирает темную тему, вы можете установить темный атрибут данных body, и пользовательский интерфейс изменится.

Вы также можете изменить стили элементов кнопок, чтобы они менялись вместе с темой.

.themeBtn {
отступ: 10 пикселей;
цвет: вар(--цвет-текст-первичный);
фон: прозрачный;
граница: 1пиксели сплошные вар(--цвет-текст-первичный);
курсор: указатель;
}

Изменение компонента кнопки для переключения стилей

Чтобы переключать стили, определенные в файле CSS, вам необходимо установить данные в элементе body в функции handleToggle().

В Button.js измените handleToggle() следующим образом:

константа handleToggle = () => {
константа newTheme = тема "легкий"? "темный": "легкий"
установить тему (новая тема)
документ.body.dataset.theme = тема
}

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

Сохранение пользовательских настроек в локальном хранилище

Вы должны получить настройки пользователя, как только отобразится компонент Button. Хук useEffect() идеально подходит для этого, так как он запускается после каждого рендера.

Прежде чем извлекать тему из локального хранилища, ее необходимо сначала сохранить.

Создайте новую функцию storeUserPreference() в Button.js.

константа storeUserSetPreference = (преф) => {
localStorage.setItem("тема", преф.);
};

Эта функция получает предпочтения пользователя в качестве аргумента и сохраняет их как элемент с именем тема.

Вы будете вызывать эту функцию каждый раз, когда пользователь переключает тему. Итак, измените функцию handleToggle(), чтобы она выглядела следующим образом:

константа handleToggle = () => {
константа newTheme = тема "легкий"? "темный": "легкий"
установить тему (новая тема)
storeUserSetPreference (новая тема)
документ.body.dataset.theme = тема
}

Следующая функция извлекает тему из локального хранилища:

константа getUserSetPreference = () => {
вернуть localStorage.getItem("тема");
};

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

использовать эффект (() => {
константа userSetPreference = getUserSetPreference();

если (userSetPreference) {
установить тему (userSetPreference)
}
документ.body.dataset.theme = тема
}, [тема])

Получение предпочтений пользователя из настроек браузера

Для еще большего удобства пользователей вы можете использовать предпочитает цветовую схему Мультимедийная функция CSS для установки темы. Это должно отражать системные настройки пользователя, которыми он может управлять через свою ОС или браузер. Настройка может быть светлой или темной. В вашем приложении вам нужно будет проверить этот параметр сразу после загрузки компонента кнопки. Это означает реализацию этой функциональности в хуке useEffect().

Во-первых, создайте функцию, которая извлекает предпочтения пользователя.

В Button.js добавьте следующее.

константа getMediaQueryPreference = () => {
константный медиазапрос = "(предпочитает цветовую схему: темный)";
константа mql = окно.matchMedia (медиазапрос);
константа имеет предпочтение = тип mql.matches "логическое";

если (имеет предпочтение) {
вернуть mql.matches? "темный": "легкий";
}
};

Затем измените хук useEffect(), чтобы получить предпочтение медиа-запроса и использовать его, если в локальном хранилище не задана тема.

использовать эффект (() => {
константа userSetPreference = getUserSetPreference();
константа mediaQueryPreference = getMediaQueryPreference();

если (userSetPreference) {
установить тему (userSetPreference)
} еще {
установить тему (mediaQueryPreference)
}

документ.body.dataset.theme = тема
}, [тема])

Если вы перезапустите приложение, тема должна соответствовать настройкам вашей системы.

Использование React Context для переключения темного режима

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

Другой подход к работе с темным режимом в React — использование контекстного API. Контекст React позволяет вам обмениваться данными между компонентами без необходимости передавать их через реквизиты. При использовании его для переключения тем вы создаете контекст темы, к которому вы можете получить доступ во всем приложении. Затем вы можете использовать значение темы для применения соответствующих стилей.

Хотя этот подход работает, использование атрибутов данных CSS проще.