1678279200
Nextcloud — это ваше собственное облако с открытым исходным кодом. Вот как сделать переключатель.
Если вы опасаетесь передавать свои данные в облачные службы, контролируемые корпорацией, но вам нравится удобство удаленного хранения и легкий доступ через Интернет, вы не одиноки. Облако популярно из-за того, что оно может делать. Но облако не обязательно должно быть закрытым . К счастью, проект Nextcloud с открытым исходным кодом предоставляет набор приложений для личного и частного облака.
Легко устанавливать и импортировать данные, включая контакты, календари и фотографии. Настоящая хитрость заключается в получении ваших данных от облачных провайдеров, таких как iCloud. В этой статье я демонстрирую шаги, которые необходимо предпринять, чтобы перенести свою цифровую жизнь на Nextcloud.
Как и в случае с устройствами Android , сначала необходимо перенести существующие данные из Apple iCloud в Nextcloud. Затем вы можете настроить две новые учетные записи для своих устройств Apple, чтобы полностью автоматически синхронизировать адресные книги и встречи. Apple поддерживает CalDAV для календарей и CardDAV для контактов, поэтому вам даже не нужно устанавливать дополнительное приложение.
Чтобы экспортировать свою адресную книгу, вы можете либо открыть приложение «Контакты» на своем iPhone/iPad, либо войти в iCloud в веб-браузере:
Выберите все записи адресной книги, которые вы хотите перенести в Nextcloud, и выберите «Файл» > «Экспорт» > «Экспорт vCard» , чтобы сохранить файл . vcfфайл на локальном диске.
Импортируйте файл . vcfфайл в Nextcloud. Для этого выберите приложение «Контакты» , нажмите «Настройки» в левом нижнем углу и нажмите кнопку «Импорт контактов» . В следующем диалоговом окне нажмите Выбрать локальный файл и откройте ранее сохраненную визитную карточку.
Чтобы настроить учетную запись CardDAV на iPhone или iPad, выберите «Настройки» > «Контакты» > «Учетные записи» > «Добавить учетную запись» :
Выберите «Другое» , а затем «Добавить учетную запись CardDAV» . В поле Сервер введите URL-адрес Nextcloud (например, https://nextcloudpi.local ). Ниже этого места для имени пользователя и пароля учетной записи Nextcloud. Откройте дополнительные настройки для новой учетной записи.
Убедитесь, что опция Использовать SSL включена. URL-адрес учетной записи обычно указывается правильно. Он содержит, среди прочего, имя хоста вашего Nextcloud и ваше имя пользователя.
Чтобы создать новую учетную запись в macOS для синхронизации адресных книг, откройте приложение «Контакты» и выберите «Добавить учетную запись» в меню «Контакты» . Установите флажок «Другая учетная запись контактов» и нажмите «Продолжить» . Вы можете принять запись CardDAV . В раскрывающемся меню «Тип учетной записи» выберите «Ввод вручную» .
(Хайке Юрзик, CC BY-SA 4.0)
Введите имя пользователя, пароль и адрес сервера Nextcloud. Текущая версия macOS требует указать порт 443 (для SSL) в адресе сервера. Например, если адрес вашего Nextcloud — https://nextcloudpi.local , а имя пользователя — hej, то введите в поле следующее:
https://nextcloudpi.local:443/remote.php/dav/principals/users/hej
Экспорт ваших календарей работает аналогичным образом. Через приложение «Календарь» вы можете сделать это с помощью iCloud в браузере, на своем смартфоне/планшете или на рабочем столе macOS.
Сначала сделайте календарь общедоступным . Это не означает, что каждый может получить доступ к вашему календарю. Он используется только для создания ссылки для подписки на календарь. Скопируйте URL-адрес в буфер обмена. Импортировать календарь напрямую в Nextcloud пока нельзя, потому что для этого нужна не ссылка, а файл .ics(iCalendar). Вот как сгенерировать такой файл по ссылке:
Скопируйте ссылку в буфер обмена
Вставьте ссылку в адресную строку веб-браузера
Измените начало URL и замените webcalнаhttp
Нажмите Enter и сохраните .icsфайл на свой диск.
(Хайке Юрзик, CC BY-SA 4.0)
Теперь вы можете импортировать .icsфайл. Для этого откройте приложение «Календарь» в Nextcloud, нажмите «Настройки календаря» в левом нижнем углу, а затем «Импортировать календарь» . Выберите .icsфайл, который вы сохранили в файловом менеджере.
Повторите этот процесс для всех календарей iCloud. После этого пришло время заменить старый сервис синхронизации iCloud.
Чтобы синхронизировать новые события с Nextcloud, настройте новую учетную запись на своих клиентских устройствах (смартфон, планшет, компьютер):
iPhone/iPad: «Настройки » / «Календарь » / «Учетные записи » / «Добавить учетную запись» , выберите «Другое» , а затем выберите «Добавить учетную запись CalDAV» . В поле «Сервер» введите локальный URL-адрес Nextcloud, то есть https://nextcloudpi.local. Вы можете увидеть место для имени пользователя и пароля учетной записи Nextcloud.
macOS: откройте приложение «Календарь» и выберите «Добавить учетную запись» в меню «Календарь» . Установите флажок «Другая учетная запись CalDAV» и нажмите «Продолжить» . В раскрывающемся меню «Тип учетной записи» выберите «Ввод вручную» . Введите имя пользователя и пароль Nextcloud, а также адрес сервера Nextcloud. Не забудьте в адресе сервера указать порт 443 (для SSL); в противном случае настройка учетной записи завершится ошибкой.
Совет: Если вы хотите синхронизировать другие файлы, такие как документы, фотографии, видео и т. д., в дополнение к вашим контактам и календарям, вы можете установить приложение Nextcloud, предлагаемое в App Store.
Оригинальный источник статьи: https://opensource.com/
1678279200
Nextcloud — это ваше собственное облако с открытым исходным кодом. Вот как сделать переключатель.
Если вы опасаетесь передавать свои данные в облачные службы, контролируемые корпорацией, но вам нравится удобство удаленного хранения и легкий доступ через Интернет, вы не одиноки. Облако популярно из-за того, что оно может делать. Но облако не обязательно должно быть закрытым . К счастью, проект Nextcloud с открытым исходным кодом предоставляет набор приложений для личного и частного облака.
Легко устанавливать и импортировать данные, включая контакты, календари и фотографии. Настоящая хитрость заключается в получении ваших данных от облачных провайдеров, таких как iCloud. В этой статье я демонстрирую шаги, которые необходимо предпринять, чтобы перенести свою цифровую жизнь на Nextcloud.
Как и в случае с устройствами Android , сначала необходимо перенести существующие данные из Apple iCloud в Nextcloud. Затем вы можете настроить две новые учетные записи для своих устройств Apple, чтобы полностью автоматически синхронизировать адресные книги и встречи. Apple поддерживает CalDAV для календарей и CardDAV для контактов, поэтому вам даже не нужно устанавливать дополнительное приложение.
Чтобы экспортировать свою адресную книгу, вы можете либо открыть приложение «Контакты» на своем iPhone/iPad, либо войти в iCloud в веб-браузере:
Выберите все записи адресной книги, которые вы хотите перенести в Nextcloud, и выберите «Файл» > «Экспорт» > «Экспорт vCard» , чтобы сохранить файл . vcfфайл на локальном диске.
Импортируйте файл . vcfфайл в Nextcloud. Для этого выберите приложение «Контакты» , нажмите «Настройки» в левом нижнем углу и нажмите кнопку «Импорт контактов» . В следующем диалоговом окне нажмите Выбрать локальный файл и откройте ранее сохраненную визитную карточку.
Чтобы настроить учетную запись CardDAV на iPhone или iPad, выберите «Настройки» > «Контакты» > «Учетные записи» > «Добавить учетную запись» :
Выберите «Другое» , а затем «Добавить учетную запись CardDAV» . В поле Сервер введите URL-адрес Nextcloud (например, https://nextcloudpi.local ). Ниже этого места для имени пользователя и пароля учетной записи Nextcloud. Откройте дополнительные настройки для новой учетной записи.
Убедитесь, что опция Использовать SSL включена. URL-адрес учетной записи обычно указывается правильно. Он содержит, среди прочего, имя хоста вашего Nextcloud и ваше имя пользователя.
Чтобы создать новую учетную запись в macOS для синхронизации адресных книг, откройте приложение «Контакты» и выберите «Добавить учетную запись» в меню «Контакты» . Установите флажок «Другая учетная запись контактов» и нажмите «Продолжить» . Вы можете принять запись CardDAV . В раскрывающемся меню «Тип учетной записи» выберите «Ввод вручную» .
(Хайке Юрзик, CC BY-SA 4.0)
Введите имя пользователя, пароль и адрес сервера Nextcloud. Текущая версия macOS требует указать порт 443 (для SSL) в адресе сервера. Например, если адрес вашего Nextcloud — https://nextcloudpi.local , а имя пользователя — hej, то введите в поле следующее:
https://nextcloudpi.local:443/remote.php/dav/principals/users/hej
Экспорт ваших календарей работает аналогичным образом. Через приложение «Календарь» вы можете сделать это с помощью iCloud в браузере, на своем смартфоне/планшете или на рабочем столе macOS.
Сначала сделайте календарь общедоступным . Это не означает, что каждый может получить доступ к вашему календарю. Он используется только для создания ссылки для подписки на календарь. Скопируйте URL-адрес в буфер обмена. Импортировать календарь напрямую в Nextcloud пока нельзя, потому что для этого нужна не ссылка, а файл .ics(iCalendar). Вот как сгенерировать такой файл по ссылке:
Скопируйте ссылку в буфер обмена
Вставьте ссылку в адресную строку веб-браузера
Измените начало URL и замените webcalнаhttp
Нажмите Enter и сохраните .icsфайл на свой диск.
(Хайке Юрзик, CC BY-SA 4.0)
Теперь вы можете импортировать .icsфайл. Для этого откройте приложение «Календарь» в Nextcloud, нажмите «Настройки календаря» в левом нижнем углу, а затем «Импортировать календарь» . Выберите .icsфайл, который вы сохранили в файловом менеджере.
Повторите этот процесс для всех календарей iCloud. После этого пришло время заменить старый сервис синхронизации iCloud.
Чтобы синхронизировать новые события с Nextcloud, настройте новую учетную запись на своих клиентских устройствах (смартфон, планшет, компьютер):
iPhone/iPad: «Настройки » / «Календарь » / «Учетные записи » / «Добавить учетную запись» , выберите «Другое» , а затем выберите «Добавить учетную запись CalDAV» . В поле «Сервер» введите локальный URL-адрес Nextcloud, то есть https://nextcloudpi.local. Вы можете увидеть место для имени пользователя и пароля учетной записи Nextcloud.
macOS: откройте приложение «Календарь» и выберите «Добавить учетную запись» в меню «Календарь» . Установите флажок «Другая учетная запись CalDAV» и нажмите «Продолжить» . В раскрывающемся меню «Тип учетной записи» выберите «Ввод вручную» . Введите имя пользователя и пароль Nextcloud, а также адрес сервера Nextcloud. Не забудьте в адресе сервера указать порт 443 (для SSL); в противном случае настройка учетной записи завершится ошибкой.
Совет: Если вы хотите синхронизировать другие файлы, такие как документы, фотографии, видео и т. д., в дополнение к вашим контактам и календарям, вы можете установить приложение Nextcloud, предлагаемое в App Store.
Оригинальный источник статьи: https://opensource.com/
1661433143
Менеджер пакетов упрощает установку приложений GNU/Linux на локальный компьютер. До того, как управление пакетами стало обычным явлением, установка приложений была утомительной и подверженной ошибкам задачей. Простота, которую диспетчер пакетов обеспечивает для установки приложения на компьютер с Linux, стала основным фактором, способствовавшим широкому внедрению Linux в качестве основной операционной системы как для деловых, так и для домашних пользователей.
Однако управление пакетами в Linux разделено. Сосуществуют две основные системы:
Эта статья предназначена для разработчиков, которые в настоящее время используют системы на основе Debian и знакомы с APT, но хотят начать использовать систему семейства Red Hat Enterprise Linux. В статье объясняются сходства и различия между APT и RPM. Я покажу, как выполнять определенные, стандартные задачи управления пакетами, используя каждую систему.
Пользователи Debian привыкли управлять своими пакетами с помощью aptкоманды. Переключение на текущий инструмент RPM dnf— тема этой статьи.
Возможно, вы также видели ссылки на yumкоманду. Оба dnfи yumявляются утилитами командной строки, которые работают с пакетами RPM. Изначально Red Hat выпускала и зависела от yum, что является аббревиатурой от Yellowdog Updater, Modified . dnf, аббревиатура от dandified yum , является последующей технологией, основанной на yum, как следует из названия.
Сегодня dnfэто утилита управления пакетами по умолчанию для Red Hat Enterprise Linux, Fedora и CentOS Stream, начиная с Fedora 22, CentOS 8 и Red Hat Enterprise Linux 8 соответственно. yumустарел как диспетчер пакетов по умолчанию в семействе дистрибутивов Red Hat, поэтому, хотя yumкоманды в настоящее время работают, лучше всего использовать только файлы dnf.
Шаблон для поиска и установки пакета Linux практически одинаков независимо от того, используете ли вы aptили dnf.
Когда вы выполняете команду для установки пакета, менеджер пакетов просматривает файлы конфигурации на локальном компьютере, чтобы определить расположение репозитория с данным пакетом в Интернете. Затем команда установки загружает пакет вместе с его зависимостями из Интернета. Наконец, менеджер пакетов устанавливает и настраивает приложение на локальном компьютере. Рисунок 1 иллюстрирует этот процесс.
Рисунок 1: Менеджер пакетов получает информацию с локального компьютера для извлечения пакета из репозитория.
Хотя базовый процесс установки аналогичен как для менеджеров пакетов RPM, так и для APT, существуют различия, когда дело доходит до реализации. Помимо используемых команд, есть небольшая разница в том, как эти команды обращаются к файлам для поиска и установки пакетов.
Когда вы вызываете команду установки менеджера пакетов, менеджер пакетов сначала проверяет, присутствует ли интересующий вас пакет и уже ли он установлен. APT ищет в /var/cache/apt/archivesкаталоге наличие .debфайла пакета. В RPM менеджер пакетов проверяет каталоги на наличие файла /var/cache/dnf/пакета ..rpm
Если пакет .debили .rpmфайл отсутствуют, программа установки проверяет файлы, описывающие расположение репозиториев в Интернете. В некоторых случаях эти файлы также могут сообщать о пакетах, хранящихся в определенном репозитории. В APT информация хранится в файле /etc/apt/sources.list или в .listфайлах в каталоге /etc/apt/sources.list.d. В RPM сведения о репозитории хранятся в .xmlфайлах или сжатых .solvxфайлах в каталоге кеша /var/cache/dnf/. Также общая информация о репозитории хранится в .repoфайлах в каталоге /etc/yum.repos.d.
После обнаружения информации о пакете и репозитории установщик переходит в удаленный репозиторий, чтобы найти и установить пакет. В некоторых случаях установщику может потребоваться обратиться к нескольким удаленным репозиториям в поисках пакета. Если программа установки не находит интересующий пакет, менеджер пакетов сообщает об ошибке.
Таким образом, общая схема обнаружения и установки пакетов для APT и RPM аналогична. Разница заключается в используемых инструментах CLI. Структура и содержимое файловой системы, используемой установщиком пакета на локальном компьютере, также отличаются.
Большинству пользователей, переходящих с Debian aptна RPM, dnfникогда не приходится задумываться о разнице между внутренним устройством менеджеров пакетов APT и RPM. Инструменты CLI абстрагируют низкоуровневые операции.
В большинстве случаев главной заботой разработчиков, переходящих с aptна, dnfявляется установка, удаление и обновление пакетов, которые мы рассмотрим в этом разделе. Но сначала я покажу вам, как добавить репозиторий в поиск и как составить список пакетов и известных репозиториев.
Чтобы установить пакет на ваш компьютер, инструмент CLI должен знать, где находятся репозитории, содержащие пакеты. Как правило, когда вы впервые настраиваете свой компьютер, независимо от того, работает ли он под управлением операционной системы из семейства Debian или семейства Red Hat Enterprise Linux, информация об основных репозиториях, в которых размещаются обычные пакеты для данной операционной системы, включается в ОС по умолчанию. . Однако могут быть случаи, когда вам нужно выполнить поиск в других репозиториях. В этом разделе показаны команды для добавления информации о репозитории на локальный компьютер.
Чтобы добавить информацию о репозитории на компьютер с Debian, Ubuntu и т. д., введите:
# add-apt-repository <repository identification information>
Например, следующая команда устанавливает информацию для базы данных MongoDB на компьютере с Debian:
# sudo add-apt-repository 'deb [arch=amd64] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse'
Примечание . Команды, изменяющие системное программное обеспечение, необходимо вводить от имени суперпользователя (root). Следовательно, эти команды имеют префикс sudo. Я показываю командную строку #как напоминание о том, что вы должны работать как root.
Чтобы добавить информацию о репозитории на компьютер под управлением Red Hat Enterprise Linux, Fedora или CentOS Stream, введите:
# dnf config-manager --add-repo <repo_url>
В следующем примере информация о зеркальном репозитории для CentOS 9 устанавливается на локальный компьютер:
# sudo dnf config-manager --add-repo="https://mirror.aarnet.edu.au/pub/centos/9"
Вы также хотите регулярно проверять актуальность текущих пакетов на хост-компьютере. Чтобы обновить существующие пакеты в Debian, выполните следующую команду:
# sudo apt update
Чтобы обновить существующие пакеты на компьютере семейства Red Hat Enterprise Linux, выполните следующую команду:
# sudo dnf update
Как упоминалось ранее, схема установки пакетов на хост-компьютер аналогична в Debian и машинах семейства Red Hat Enterprise Linux.
Чтобы установить пакет на машину с Debian, введите:
# sudo apt install <package_name>
В следующем примере jqутилита для разбора и фильтрации файлов JSON устанавливается на компьютер с Debian:
# sudo apt install jq
Чтобы установить пакет на машину семейства Red Hat Enterprise Linux, введите:
# sudo dnf install <package_name>
В следующем примере jqутилита устанавливается на машину семейства Red Hat Enterprise Linux:
# sudo dnf install jq
Схема удаления приложения аналогична для систем на основе Debian и Red Hat Enterprise Linux. Разница заключается в используемом инструменте CLI.
Чтобы удалить пакет на машине с Debian, введите:
# sudo apt remove <package_name>
Копировать фрагмент
В следующем примере jqутилита удаляется с компьютера с Debian:
# sudo apt remove jq
Чтобы удалить пакет в Red Hat Enterprise Linux, введите:
# sudo dnf remove <package_name>
В следующем примере jqутилита удаляется с компьютера Red Hat Enterprise Linux:
# sudo dnf remove jq
Список пакетов, установленных на локальном компьютере, может предоставить полезную информацию, особенно для аудита и управления системой.
Чтобы вывести список всех пакетов, установленных на машине с Debian, введите:
$ apt list
В следующем примере показано, как использовать эту команду в сочетании с grepкомандой для фильтрации результатов с помощью регулярного выражения. Регулярное выражение в этом примере сохраняет только те строки, которые начинаются с символов git:
$ apt list | grep '^git'
Следующий вывод показывает частичный список результатов:
git-annex-remote-rclone/focal,focal 0.6-1 all
git-annex/focal 8.20200226-1 amd64
git-build-recipe/focal,focal 0.3.6 all
git-buildpackage-rpm/focal,focal 0.9.19 all
git-buildpackage/focal,focal 0.9.19 all
git-cola/focal,focal 3.6-1 all
git-crecord/focal,focal 20190217~git-1 all
.
.
.
Чтобы получить список пакетов, установленных на компьютере с Red Hat Enterprise Linux, введите:
$ dnf list installed
В следующем примере показано, как использовать эту команду для получения списка пакетов, установленных на компьютере с Red Hat Enterprise Linux, а затем выбрать строки, начинающиеся с git:
$ dnf list installed | grep '^git'
Команда выдает следующий вывод:
git.x86_64 2.35.3-1.fc35 @updates
git-core.x86_64 2.35.3-1.fc35 @updates
git-core-doc.noarch 2.35.3-1.fc35 @updates
В Debian и семействе Red Hat Enterprise Linux используются разные методы вывода списка репозиториев, известных данному локальному компьютеру.
При установке Debian по умолчанию ни одна команда не имеет логики для сообщения об известных репозиториях. Вместо этого вы должны усовершенствовать существующие команды.
Один из способов получить список известных репозиториев — использовать apt-cache policyкоманду для возврата известных репозиториев, как показано в следующем примере:
$ apt-cache policy |grep http |awk '{print $2 " " $3}' |sort -u
Мы видели grepуже. Команда awk, которая следует в конвейере, выбирает второе и третье слова каждой строки. Полная команда выводит следующий результат:
http://dl.google.com/linux/chrome/deb stable/main
http://ppa.launchpad.net/ansible/ansible/ubuntu focal/main
http://security.ubuntu.com/ubuntu focal-security/main
http://security.ubuntu.com/ubuntu focal-security/multiverse
http://security.ubuntu.com/ubuntu focal-security/restricted
http://security.ubuntu.com/ubuntu focal-security/universe
http://us.archive.ubuntu.com/ubuntu focal-backports/main
http://us.archive.ubuntu.com/ubuntu focal-backports/universe
http://us.archive.ubuntu.com/ubuntu focal/main
http://us.archive.ubuntu.com/ubuntu focal/multiverse
http://us.archive.ubuntu.com/ubuntu focal/restricted
http://us.archive.ubuntu.com/ubuntu focal/universe
http://us.archive.ubuntu.com/ubuntu focal-updates/main
http://us.archive.ubuntu.com/ubuntu focal-updates/multiverse
http://us.archive.ubuntu.com/ubuntu focal-updates/restricted
http://us.archive.ubuntu.com/ubuntu focal-updates/universe
Другой способ получить список репозиториев — проверить записи, начинающиеся с символов debв etc/apt/sources.listфайлах:
# sudo grep -rhE ^deb /etc/apt/sources.list*
Команда выдает следующий вывод:
deb http://us.archive.ubuntu.com/ubuntu/ focal main restricted
deb http://us.archive.ubuntu.com/ubuntu/ focal-updates main restricted
deb http://us.archive.ubuntu.com/ubuntu/ focal universe
deb http://us.archive.ubuntu.com/ubuntu/ focal-updates universe
deb http://us.archive.ubuntu.com/ubuntu/ focal multiverse
Все проще при использовании dnfв семействе Red Hat Enterprise Linux. Команда dnf repolistвыводит список репозиториев, известных локальному компьютеру.
В следующем примере показан результат выполнения dnf repolistкоманды. По умолчанию команда отображает два столбца repo idи repo name:
$ dnf repolist
Команда выдает следующий вывод:
repo id repo name
fedora Fedora 35 - x86_64
fedora-cisco-openh264 Fedora 35 openh264 (From Cisco) - x86_64
fedora-modular Fedora Modular 35 - x86_64
updates Fedora 35 - x86_64 - Updates
updates-modular Fedora Modular 35 - x86_64 - Updates
Переход с Debian или Ubuntu на Red Hat Enterprise Linux, Fedora или CentOS Stream требует некоторой настройки, когда дело доходит до работы в командной строке, но переход может быть простым.
Шаблоны для установки и удаления приложений удивительно похожи, но инструменты командной строки отличаются. Ubuntu/Debian использует apt. Семейство Red Hat Enterprise Linux использует dnf. Оба инструмента командной строки поддерживают похожие подкоманды, что наиболее очевидно для apt installи dnf install.
Методы отслеживания известных репозиториев различаются в разных операционных системах. К счастью для тех, кто переходит на семейство Red Hat Enterprise Linux, перечисление репозиториев намного проще, поскольку для этого требуется только dnf repolistкоманда. Список репозиториев в Debian требует дополнительной работы.
Изучение деталей новой технологии требует времени. При переходе с aptна dnf, вам придется предвидеть кривую обучения. Но кривая обучения не крутая, и вы быстро освоитесь.
#command #package #linux
1658404090
React Redux — чрезвычайно популярный пакет, который загружают около 4,5 миллионов раз в неделю. Еще один популярный пакет, Redux Saga, представляет собой менеджер побочных эффектов Redux — только его загружают более 900 000 раз в неделю. Сочетание React Redux с Redux Saga или Redux Thunk является одним из наиболее распространенных дополнений к проектам React.
Однако за последний год или около того React Query быстро набирает популярность как альтернатива React Redux. В прошлом году у React Query было всего около 120 тысяч загрузок в неделю, но по состоянию на октябрь 2021 года загрузки React Query почти в шесть раз чаще, почти 700 тысяч загрузок в неделю.
React Query имеет некоторые явные преимущества перед React Redux для хранения состояния сервера.
Основное преимущество React Query заключается в том, что его гораздо проще написать, чем React Redux. В React Redux для операции оптимистического обновления поля требуется три действия (запрос, успех и сбой), три редуктора (запрос, успех и сбой), одно промежуточное ПО и селектор для доступа к данным. Однако в React Query аналогичная настройка значительно проще, поскольку для этого требуется только одна мутация (которая состоит из четырех функций) и один запрос.
Еще одно преимущество React Query заключается в том, что он более плавно работает с инструментами навигации, встроенными во многие IDE. С React Query вы можете использовать «Перейти к определению», чтобы легче добраться до вашей мутации, тогда как с Redux Saga вы должны искать во всей кодовой базе использование действия.
В любом существующем проекте переход на использование нового пакета может оказаться непростой задачей. Сегодня, чтобы сделать эту задачу более управляемой, мы рассмотрим пример, в котором приложение, использующее React Redux с Redux Saga, будет перенесено в React Query.
Для начала давайте взглянем на базовую оптимистичную настройку Redux с тремя редьюсерами, тремя действиями, селектором и сагой.
В нашем примере у нас есть веб-сайт React, где пользователь может ввести свое имя, и его имя отображается на странице. Селектор используется на странице React для отображения введенного пользователем имени. Когда пользователь вводит свое имя, отправляется действие запроса, которое вызывает запуск редуктора и саги. Редюсер оптимистично обновляет хранилище с новым значением имени. Тем временем сага обращается к серверной части, чтобы сохранить имя пользователя.
Если серверная часть возвращает HTTP-успех, сага отправляет действие об успешном завершении. Действие успеха вызывает запуск редюсера, который обновляет значение имени в хранилище.
Если серверная часть возвращает ошибку HTTP, сага отправляет действие ошибки. Действие при сбое вызывает запуск редуктора, который изменяет значение в хранилище обратно на его значение до оптимистического обновления.
ИмяКомпонент.tsx
import React, {
ChangeEvent,
FormEvent,
FunctionComponent,
useCallback,
useEffect,
useState,
} from "react";
import { useDispatch, useSelector } from "react-redux";
import { selectName, updateNameRequest } from "../redux/slice";
export const NameComponent: FunctionComponent = () => {
const name = useSelector(selectName);
const [localName, setLocalName] = useState<string>("");
const dispatch = useDispatch();
useEffect(() => {
if (name) setLocalName(name);
}, [name]);
const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {
setLocalName(event.target.value);
}, []);
const handleSubmit = useCallback(
(event: FormEvent) => {
dispatch(updateNameRequest({ name: localName }));
event.preventDefault();
},
[dispatch, localName]
);
return (
<div>
<p>{`Your name is ${name ?? "unknown to me"}.`}</p>
<form onSubmit={handleSubmit}>
<label>
{`Enter name: `}
<input type="text" onChange={handleChange} />
</label>
<input type="submit" value="Update Name" />
</form>
</div>
);
};
slice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { RootState } from "..";
export interface NameState {
name: string | null;
error: string | null;
}
export const initialState: NameState = {
name: null,
error: null,
};
export const nameSlice = createSlice({
name: "name",
initialState,
reducers: {
updateNameRequest: (state, action: PayloadAction<{ name: string }>) => ({
...state,
...action.payload,
}),
updateNameSuccess: (state, action: PayloadAction<{ name: string }>) => ({
...state,
...action.payload,
}),
updateNameFailure: (
state,
action: PayloadAction<{ error: string; name: string }>
) => ({
...state,
...action.payload,
}),
},
});
export const selectName = (state: RootState) => state.name;
const { actions, reducer } = nameSlice;
export const { updateNameRequest, updateNameSuccess, updateNameFailure } =
actions;
export type NameAction =
| typeof updateNameRequest
| typeof updateNameSuccess
| typeof updateNameFailure;
export { reducer as nameReducer };
саги.тс
import { ActionType } from "typesafe-actions";
import { call, put, select, takeEvery } from "redux-saga/effects";
import {
selectName,
updateNameFailure,
updateNameRequest,
updateNameSuccess,
} from "./slice";
import { updateName } from "../api/api";
function* updateNameSaga(action: ActionType<typeof updateNameRequest>) {
const { name } = action.payload;
const oldName: string = yield select(selectName);
try {
yield call(updateName, name);
yield put(updateNameSuccess(action.payload));
} catch (error) {
yield put(
updateNameFailure({ error: (error as Error).message, name: oldName })
);
}
}
export function* nameSagas() {
yield takeEvery(updateNameRequest, updateNameSaga);
}
store.ts
import { applyMiddleware, createStore } from "@reduxjs/toolkit";
import createSagaMiddleware from "redux-saga";
import { nameSagas } from "../redux/sagas";
import { nameReducer } from "../redux/slice";
const sagaMiddleware = createSagaMiddleware();
export default function configureStore() {
const store = createStore(nameReducer, applyMiddleware(sagaMiddleware));
sagaMiddleware.run(nameSagas);
return { store };
}
Первым шагом нашего преобразования является создание запроса для замены селектора и хранилища. Ниже приведен пользовательский хук React, который содержит useQuery для хранения имени пользователя. В этом примере getName — это вызов серверной части для получения имени, хранящегося в базе данных.
import { getName } from "../api/api";
export const getNameQuery = () => ({
queryKey: ["name"],
queryFn: getName,
});
Следующим шагом нашего преобразования является создание оптимистичной мутации для замены саги, редукторов и действий Redux. Ниже представлена оптимистичная мутация пользовательского хука React, который оптимистично обновляет запрос и делает запрос недействительным после обновления.
import { useMutation, useQueryClient } from "react-query";
import { updateName } from "../api/api";
export const useEditName = () => {
const qc = useQueryClient();
return useMutation<void, unknown, { newName: string }, string>(
async ({ newName }) => {
await updateName(newName);
},
{
onMutate: async ({ newName }) => {
await qc.cancelQueries("name");
const currentName: string | undefined = qc.getQueryData("name");
qc.setQueryData("name", newName);
return currentName;
},
onError: (_error, _variables, context) => {
if (context) qc.setQueryData("name", context);
},
onSettled: async () => {
qc.invalidateQueries("name");
},
}
);
};
В этом случае функция мутации вызывает серверную часть с updateName, чтобы изменить имя, хранящееся в базе данных.
Перед функцией мутации Redux Query выполняет onMutate . В этом случае мы отменяем обновляемый запрос, получаем текущее значение запроса и обновляем значение запроса новым значением. Затем мы возвращаем старое значение для запроса, чтобы мы могли вернуться, если наш оптимизм не окупится.
Если функция мутации выдает ошибку, Redux Query выполняет onError . Все, что нам нужно сделать, это установить запрос в параметр контекста, если внутренний вызов завершится ошибкой.
Наконец, Redux Query выполняет onSettled , что просто делает запрос недействительным, поэтому Redux Query знает, что данные устарели. Это заставляет Redux Query получать новое имя из бэкэнда.
Новый запрос и мутацию можно использовать в компоненте React следующим образом. В итоге у нас будет настройка React Query с оптимистичной мутацией. Всего два хука заменяют оригинальную настройку React Redux и Redux Saga.
имя.ts
import { useMutation, useQueryClient } from "react-query";
import { getName, updateName } from "../api/api";
export const getNameQuery = () => ({
queryKey: ["name"],
queryFn: getName,
});
export const useEditName = () => {
const qc = useQueryClient();
return useMutation<void, unknown, { newName: string }, string>(
async ({ newName }) => {
await updateName(newName);
},
{
onMutate: async ({ newName }) => {
await qc.cancelQueries("name");
const currentName: string | undefined = qc.getQueryData("name");
qc.setQueryData("name", newName);
return currentName;
},
onError: (_error, _variables, context) => {
if (context) qc.setQueryData("name", context);
},
onSettled: async () => {
qc.invalidateQueries("name");
},
}
);
};
ИмяКомпонент.tsx
import React, {
ChangeEvent,
FormEvent,
FunctionComponent,
useCallback,
useEffect,
useState,
} from "react";
import { useQuery } from "react-query";
import { getNameQuery, useEditName } from "../dataLayer/name";
export const NameComponent: FunctionComponent = () => {
const editNameMutation = useEditName();
const { data: name } = useQuery(getNameQuery());
const [localName, setLocalName] = useState<string>("");
useEffect(() => {
if (name) setLocalName(name);
}, [name]);
const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {
setLocalName(event.target.value);
}, []);
const handleSubmit = useCallback(
(event: FormEvent) => {
editNameMutation.mutate({ newName: localName });
event.preventDefault();
},
[editNameMutation, localName]
);
return (
<div>
<p>{`Your name is ${name ?? "unknown to me"}.`}</p>
<form onSubmit={handleSubmit}>
<label>
{`Enter name: `}
<input type="text" onChange={handleChange} />
</label>
<input type="submit" value="Update Name" />
</form>
</div>
);
};
Последним шагом для этой настройки является упаковка приложения в QueryClientProvider.
App.tsx
import React from "react";
import { QueryClient, QueryClientProvider } from "react-query";
import "./App.css";
import { NameComponent } from "./components/NameComponent";
const queryClient = new QueryClient();
function App() {
return (
<div className="App">
<header className="App-header">
<QueryClientProvider client={queryClient}>
<NameComponent />
</QueryClientProvider>
</header>
</div>
);
}
export default App;
React Query быстрее написать, легче ориентироваться, и теперь, когда вы знаете, как его использовать, это альтернатива хранению и обновлению состояния сервера с помощью React Redux с Redux Saga или Redux Thunk.
Ссылка: https://blog.theodo.com/2021/10/migrating-from-react-redux-to-react-query/
#redux #react #reactjs #reactquery
1660298594
Привет всем, сегодня я собираюсь показать вам, как вы можете перейти на другую страницу на веб-сайте, используя react-router-dom.
React Router — это стандартная библиотека для маршрутизации в React. Он обеспечивает навигацию между представлениями различных компонентов в приложении React, позволяет изменять URL-адрес браузера и поддерживает синхронизацию пользовательского интерфейса с URL-адресом.
Сначала введите эти команды в свой терминал:
npm install --save react-router-dom reactstrap bootstrap
Затем мы собираемся импортировать необходимые модули-
import React,{useState} from 'react'
import {Navbar,NavbarBrand,Nav,NavItem,NavLink,Collapse,NavbarToggler} from 'reactstrap';//importing react-strap components
import {BrowserRouter as Router,Link,Route,Routes} from 'react-router-dom';//importing routing elements
Сначала мы создадим три функции для страниц ГЛАВНАЯ, ИНФОРМАЦИЯ и КОНТАКТЫ, которые мы будем использовать для маршрутизации.
/Home page function
function Home() {
return <h1 className="text-center display-3 text-primary">This is Home Page</h1>
}//About page function
function About() {
return <h1 className="text-center display-3 text-success">This is About Page</h1>
}//Contact page function
function Contact() {
return <h1 className="text-center display-3 text-danger">This is Contact Page</h1>
}
Затем мы будем использовать компонент маршрутизатора в качестве точки входа в панель навигации.
<Router>
//your navbar
</Router>
Затем мы создадим панель навигации, используя react-strap.
<Navbar dark color="faded" className="text-dark" style={{backgroundColor:"#1F2833"}}>
<NavbarBrand style={{color:"peachpuff",fontSize:"3rem"}}>
Coder Academy
</NavbarBrand>
<NavbarToggler onClick={isToggle} /> <Collapse isOpen={toggle} navbar>
<Nav navbar className="text-center"> <NavItem>
<NavLink style={Links}>
<Link to="/">Home</Link>
</NavLink>
</NavItem>
<NavItem>
<NavLink style={Links}>
<Link to="/about">About</Link>
</NavLink>
</NavItem>
<NavItem>
<NavLink style={Links}>
<Link to="/contact">Contact</Link>
</NavLink>
</NavItem> </Nav>
</Collapse>
</Navbar>
Вы заметили, что мы использовали теги Link для переноса наших ссылок?
Ну, это компонент реактивного маршрутизатора, который указывает путь, по которому будет проходить ссылка, когда вы нажмете на эту ссылку.
Вы можете использовать тег Link следующим образом.
<Link to="/">Home</Link>
Здесь атрибут «to» используется для указания URL-адреса, на который ведет ссылка.
Далее мы будем использовать тег Switch, чтобы предоставить компоненты, которые будут видны, когда мы перейдем к некоторому пути, используя нашу ссылку.
Вот как вы можете использовать тег Routes.
<Routes>
<Route exact path="/"
element={<Home />} /> <Route path="/about"
element={<About />} /> <Route path="/contact"
element={<Contact />} />
</Routes>
Вот полный код -
import React,{useState} from 'react'
import {Navbar,NavbarBrand,Nav,NavItem,NavLink,Collapse,NavbarToggler} from 'reactstrap';//importing react-strap components
import {BrowserRouter as Router,Link,Route,Switch} from 'react-router-dom';//importing routing elements
//Styling the Links
const Links = {
color:"palevioletred",
fontSize:"2.5rem",
margin:"2rem 0",
fontWeight:"600",
}//Home page function
function Home() {
return <h1 className="text-center display-3 text-primary">This is Home Page</h1>
}//About page function
function About() {
return <h1 className="text-center display-3 text-success">This is About Page</h1>
}//Contact page function
function Contact() {
return <h1 className="text-center display-3 text-danger">This is Contact Page</h1>
}function ReactStrap() {
const [toggle, setToggle] = useState(false); const isToggle = () => setToggle(!toggle);
return (
<div>
<Router>
<Navbar dark color="faded" className="text-dark" style={{backgroundColor:"#1F2833"}}>
<NavbarBrand style={{color:"peachpuff",fontSize:"3rem"}}>
Coder Academy
</NavbarBrand>
<NavbarToggler onClick={isToggle} /> <Collapse isOpen={toggle} navbar>
<Nav navbar className="text-center"> <NavItem>
<NavLink style={Links}>
<Link to="/">Home</Link>
</NavLink>
</NavItem><NavItem>
<NavLink style={Links}>
<Link to="/about">About</Link>
</NavLink>
</NavItem>
<NavItem>
<NavLink style={Links}>
<Link to="/contact">Contact</Link>
</NavLink>
</NavItem>
</Nav>
</Collapse>
</Navbar> <Routes>
<Route exact path="/"
element={<Home />} /> <Route path="/about"
element={<About />} /> <Route path="/contact"
element={<Contact />} />
</Routes></Router> </div>
)
}export default ReactStrap
Ссылка: https://faun.pub/routings-in-react-js-a2c943514b8c
#react #reactjs
1648618217
Как мы сообщали в сообщении о выпуске , React 18 представляет функции, основанные на нашем новом параллельном рендерере, со стратегией постепенного внедрения для существующих приложений. В этом посте мы проведем вас через шаги по обновлению до React 18.
Пожалуйста , сообщайте о любых проблемах , с которыми вы столкнетесь при обновлении до React 18.
Примечание для пользователей React Native: React 18 будет поставляться в будущей версии React Native. Это связано с тем, что React 18 опирается на новую архитектуру React Native, чтобы воспользоваться новыми возможностями, представленными в этом блоге. Для получения дополнительной информации см . основной доклад React Conf здесь .
Чтобы установить последнюю версию React:
npm install react react-dom
Или, если вы используете пряжу:
yarn add react react-dom
При первой установке React 18 вы увидите предупреждение в консоли:
ReactDOM.render больше не поддерживается в React 18. Вместо этого используйте createRoot. Пока вы не переключитесь на новый API, ваше приложение будет работать так, как если бы оно работало под управлением React 17. Подробнее: https://reactjs.org/link/switch-to-createroot .
React 18 представляет новый корневой API, который обеспечивает лучшую эргономику для управления корнями. Новый корневой API также включает новый параллельный рендерер, который позволяет вам использовать параллельные функции.
// Before
import { render } from 'react-dom';
const container = document.getElementById('app');
render(<App tab="home" />, container);
// After
import { createRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = createRoot(container);
root.render(<App tab="home" />);
Мы также изменились unmountComponentAtNode
на root.unmount
:
// Before
unmountComponentAtNode(container);
// After
root.unmount();
Мы также убрали callback из рендера, так как он обычно не дает ожидаемого результата при использовании Suspense:
// Before
const container = document.getElementById('app');
ReactDOM.render(<App tab="home" />, container, () => {
console.log('rendered');
});
// After
function AppWithCallbackAfterRender() {
useEffect(() => {
console.log('rendered');
});
return <App tab="home" />
}
const container = document.getElementById('app');
const root = ReactDOM.createRoot(container);
root.render(<AppWithCallbackAfterRender />);
Примечание. Не существует полной замены старого API обратного вызова рендеринга — это зависит от вашего варианта использования. Дополнительную информацию см. в публикации рабочей группы « Замена рендеринга на createRoot» .
Наконец, если ваше приложение использует рендеринг на стороне сервера с гидратацией, обновите hydrate
его до hydrateRoot
:
// Before
import { hydrate } from 'react-dom';
const container = document.getElementById('app');
hydrate(<App tab="home" />, container);
// After
import { hydrateRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = hydrateRoot(container, <App tab="home" />);
// Unlike with createRoot, you don't need a separate root.render() call here.
Для получения дополнительной информации см . обсуждение рабочей группы здесь .
В этом выпуске мы перерабатываем наши react-dom/server
API, чтобы полностью поддерживать приостановку на сервере и Streaming SSR. В рамках этих изменений мы объявляем устаревшим API потоковой передачи Node, который не поддерживает инкрементную потоковую передачу Suspense на сервере.
Использование этого API теперь будет предупреждать:
renderToNodeStream
: Устарело ⛔️️Вместо этого для потоковой передачи в средах Node используйте:
renderToPipeableStream
: Новое ✨Мы также представляем новый API для поддержки потоковой передачи SSR с Suspense для современных пограничных сред выполнения, таких как рабочие Deno и Cloudflare:
renderToReadableStream
: Новое ✨Следующие API продолжат работать, но с ограниченной поддержкой приостановки:
renderToString
: Ограничено ⚠️renderToStaticMarkup
: Ограничено ⚠️Наконец, этот API будет продолжать работать для рендеринга электронных писем:
renderToStaticNodeStream
Для получения дополнительной информации об изменениях в API-интерфейсах рендеринга на сервере см. публикацию рабочей группы « Обновление до React 18 на сервере », подробный обзор новой архитектуры Suspense SSR и выступление Shaundai Person о потоковом рендеринге на сервере с помощью Suspense на React Conf 2021.
React 18 добавляет готовые улучшения производительности, выполняя больше пакетной обработки по умолчанию. Пакетная обработка — это когда React группирует несколько обновлений состояния в один повторный рендеринг для повышения производительности. До React 18 мы только группировали обновления внутри обработчиков событий React. Обновления внутри промисов, setTimeout, встроенных обработчиков событий или любых других событий по умолчанию не пакетировались в React:
// Before React 18 only React events were batched
function handleClick() {
setCount(c => c + 1);
setFlag(f => !f);
// React will only re-render once at the end (that's batching!)
}
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React will render twice, once for each state update (no batching)
}, 1000);
Начиная с React 18 с createRoot
, все обновления будут автоматически пакетироваться, независимо от того, откуда они происходят. Это означает, что обновления внутри тайм-аутов, промисов, собственных обработчиков событий или любых других событий будут пакетироваться так же, как обновления внутри событий React:
// After React 18 updates inside of timeouts, promises,
// native event handlers or any other event are batched.
function handleClick() {
setCount(c => c + 1);
setFlag(f => !f);
// React will only re-render once at the end (that's batching!)
}
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React will only re-render once at the end (that's batching!)
}, 1000);
Это критическое изменение, но мы ожидаем, что это приведет к меньшему объему рендеринга и, следовательно, к повышению производительности ваших приложений. Чтобы отказаться от автоматической пакетной обработки, вы можете использовать flushSync
:
import { flushSync } from 'react-dom';
function handleClick() {
flushSync(() => {
setCounter(c => c + 1);
});
// React has updated the DOM by now
flushSync(() => {
setFlag(f => !f);
});
// React has updated the DOM by now
}
Дополнительные сведения см. в подробном обзоре автоматической пакетной обработки .
В рабочей группе React 18 мы работали с сопровождающими библиотек над созданием новых API, необходимых для поддержки одновременного рендеринга для конкретных вариантов использования в таких областях, как стили и внешние хранилища. Для поддержки React 18 некоторым библиотекам может потребоваться переключиться на один из следующих API:
useSyncExternalStore
— это новый хук, который позволяет внешним хранилищам поддерживать параллельное чтение, заставляя обновления в хранилище быть синхронными. Этот новый API рекомендуется для любой библиотеки, которая интегрируется с состоянием, внешним по отношению к React. Для получения дополнительной информации см . обзорную публикацию useSyncExternalStore и подробные сведения об API useSyncExternalStore .useInsertionEffect
— это новый хук, который позволяет библиотекам CSS-in-JS решать проблемы с производительностью при внедрении стилей при рендеринге. Если вы еще не создали библиотеку CSS-in-JS, мы не ожидаем, что вы когда-либо будете ее использовать. Этот хук запустится после изменения DOM, но до того, как эффекты макета прочитают новый макет. Это решает проблему, которая уже существует в React 17 и более ранних версиях, но еще более важна в React 18, поскольку React уступает браузеру во время одновременного рендеринга, давая ему возможность пересчитать макет. Дополнительные сведения см. в Руководстве по обновлению библиотеки для<style>
.В React 18 также представлены новые API для параллельного рендеринга, такие как startTransition
, useDeferredValue
и useId
, о которых мы расскажем подробнее в посте о выпуске .
В будущем мы хотели бы добавить функцию, которая позволит React добавлять и удалять разделы пользовательского интерфейса при сохранении состояния. Например, когда пользователь перемещается от экрана к экрану и обратно, React должен иметь возможность сразу же отобразить предыдущий экран. Для этого React размонтировал и перемонтировал деревья, используя то же состояние компонента, что и раньше.
Эта функция повысит производительность React «из коробки», но требует, чтобы компоненты были устойчивы к многократному монтированию и удалению эффектов. Большинство эффектов будут работать без каких-либо изменений, но некоторые эффекты предполагают, что они установлены или уничтожены только один раз.
Чтобы помочь выявить эти проблемы, React 18 вводит новую проверку только для разработки в строгом режиме. Эта новая проверка будет автоматически демонтировать и повторно монтировать каждый компонент всякий раз, когда компонент монтируется в первый раз, восстанавливая предыдущее состояние при втором монтировании.
До этого изменения React монтировал компонент и создавал эффекты:
* React mounts the component.
* Layout effects are created.
* Effect effects are created.
В строгом режиме в React 18 React будет имитировать размонтирование и повторное монтирование компонента в режиме разработки:
* React mounts the component.
* Layout effects are created.
* Effect effects are created.
* React simulates unmounting the component.
* Layout effects are destroyed.
* Effects are destroyed.
* React simulates mounting the component with the previous state.
* Layout effect setup code runs
* Effect setup code runs
Дополнительные сведения см. в сообщениях рабочей группы о добавлении повторно используемого состояния в StrictMode и о том, как поддерживать повторно используемое состояние в эффектах .
Когда вы впервые обновляете свои тесты для использования createRoot
, вы можете увидеть это предупреждение в своей тестовой консоли:
Текущая среда тестирования не настроена для поддержки действия(…)
Чтобы исправить это, установите globalThis.IS_REACT_ACT_ENVIRONMENT
перед true
запуском теста:
// In your test setup file
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
Цель флага — сообщить React, что он работает в среде, похожей на модульное тестирование. React будет регистрировать полезные предупреждения, если вы забудете обернуть обновление файлом act
.
Вы также можете установить флаг, false
чтобы сообщить React, что act
он не нужен. Это может быть полезно для сквозных тестов, имитирующих полную среду браузера.
В конце концов, мы ожидаем, что библиотеки тестирования настроят это автоматически. Например, следующая версия React Testing Library имеет встроенную поддержку React 18 без какой-либо дополнительной настройки.
Дополнительные сведения об act
API тестирования и связанных с ним изменениях доступны в рабочей группе.
В этом выпуске React прекращает поддержку Internet Explorer, поддержка которого прекратится 15 июня 2022 года . Мы вносим это изменение сейчас, потому что новые функции, представленные в React 18, созданы с использованием современных функций браузера, таких как микрозадачи, которые не могут быть адекватно заполнены в IE.
Если вам нужна поддержка Internet Explorer, мы рекомендуем вам остаться с React 17.
react-dom
: ReactDOM.render
устарело. Его использование предупредит и запустит ваше приложение в режиме React 17.react-dom
: ReactDOM.hydrate
устарело. Его использование предупредит и запустит ваше приложение в режиме React 17.react-dom
: ReactDOM.unmountComponentAtNode
устарело.react-dom
: ReactDOM.renderSubtreeIntoContainer
устарело.react-dom/server
: ReactDOMServer.renderToNodeStream
устарело.<Suspense>
границы в дереве. Это гарантирует согласованность гидратированного дерева и позволяет избежать потенциальных дыр в конфиденциальности и безопасности, которые могут быть вызваны несоответствием гидратации.Promise
, Symbol
и Object.assign
. Если вы поддерживаете более старые браузеры и устройства, такие как Internet Explorer, которые изначально не предоставляют современные функции браузера или имеют несовместимые реализации, рассмотрите возможность включения глобального полифилла в связанное приложение.undefined
: React больше не предупреждает, если вы возвращаетесь undefined
из компонента. Это делает допустимые возвращаемые значения компонентов согласованными со значениями, разрешенными в середине дерева компонентов. Мы предлагаем использовать линтер, чтобы предотвратить такие ошибки, как забывание return
инструкции перед JSX.act
предупреждения теперь являются необязательными: если вы выполняете сквозные тесты, act
предупреждения не нужны. Мы ввели механизм отказа , поэтому вы можете включить их только для модульных тестов, где они полезны и выгодны.setState
несмонтированных компонентах: ранее React предупреждал об утечках памяти при вызове setState
несмонтированного компонента. Это предупреждение было добавлено для подписок, но люди в основном сталкиваются с ним в сценариях, где состояние настроек в порядке, а обходные пути ухудшают код. Мы удалили это предупреждение.renderToString
: больше не будет ошибки при приостановке на сервере. Вместо этого он выдаст резервный HTML-код для ближайшей <Suspense>
границы, а затем повторит попытку рендеринга того же содержимого на клиенте. По-прежнему рекомендуется переключиться на потоковый API, например renderToPipeableStream
или renderToReadableStream
вместо этого.renderToStaticMarkup
: больше не будет ошибки при приостановке на сервере. Вместо этого он выдаст резервный HTML-код для ближайшей <Suspense>
границы и повторит попытку рендеринга на клиенте.Вы можете просмотреть полный список изменений здесь .
Оригинальный источник статьи на https://reactjs.org