Продвинутое использование
Last updated
Was this helpful?
Last updated
Was this helpful?
ОБНОВЛЕНИЕ 2018: в учебнике хорошая теория, но ему уже два года. Проверяйте версии пакетов. За выходом нового учебника можно следить в или
На так же проводятся бесплатные вебинары, публикуются переводы и авторские материалы, !
В этом разделе мы посмотрим как изменение state влияет на компонент и немного "зацепим" stateless архитектуру.
Все указано в подзаголовке, предлагаю нам в этом убедиться:
фрагмент компонента <Article />
:
Очистите консоль, и нажмите подробнее на любой из новостей:
Убедились? Запомните первое правило: нельзя вызывать setState в render: реакт видит изменилось состояние - начинает перерисовывать компонент - видит что изменилось состояние - начинает перерисовывать компонент...
Второе правило: render - дорогостоящая операция, поэтому внимательно относитесь к тому, где вы вызываете setState, и что это за собой влечет. Банальные console.log'и могут вам в этом помочь.
Очевидно, что если перерисовывается родительский компонент, то будут перерисованы и все дочерние компоненты. Дальше мы с вами пройдем разные "стадии жизни" компонента, и убедимся, что во время его "перерисовки" могут выполняться разные дорогостоящие операции и даже ajax-запросы. Пока что, просто убедимся, что вызов setState родителя - перерисует дочерние компоненты. Для этого предлагаю создать обработчик onClick на фразе "Всего новостей".
Попробуйте сами.
Задача: Необходимо добавить компоненту <News />
свойство состояния - counter, в котором хранится количество кликов по фразе. То есть обычный автоинкремент.
В решении важно использовать this.setState({counter: ++this.state.counter})
, об этом мы подробно поговорим после решения, которое представлено ниже как обычно в виде подсказок и полностью.
Подсказка #1: добавьте метод getInitialState в компонент <News />
для создания начального состояния.
Подсказка #2: добавьте обработчик onClick с функцией, которая будет увеличивать cчетчик (следовательно изменять state, следовательно вызывать this.setState... ).
Решение: Полный код компонента <News />
Проверьте в браузере. Если вы не удаляли console.log из компонента <Article />
- на каждый клик по фразе "Всего новостей", в консоли будет появляться по 3 "перерисовки".
Поговорим о: this.setState({counter: ++this.state.counter })
Почему же, было важно использовать именно префиксную запись ++, а не постфиксную? Сначала вспомним теорию:
++ перед переменной (префикс) - сначала увеличивает ее на 1, а потом возвращает значение;
++ после переменной (постфикс) - сначала вернет значение, а потом увеличит значение переменной;
В таком случае, мы должны были бы потерять всего 1 клик, не так ли? Проверьте в консоли следующим образом: откройте вкладку React в консоли, выберите компонент <News />
, начните кликать на фразу "Всего новостей"
Изменяется ли значение counter, если используется префиксная запись?
Да, изменяется:
Изменяется ли значение counter, если используется постфиксная запись?
Нет, не изменяется вообще. (убедитесь сами)
setState() - не изменяет this.state немедленно, а создает очередь изменений состояния. Доступ к this.state после вызова метода, потенциально может вернуть имеющееся (что равносильно - бывшее) значение.
Самое время крикнуть - верните мои деньги назад, и уйти... Но, не все так плачевно. Теперь вы знаете об этой особенности, и будете если что вооружены. Зачем так сделано? Вероятно, для оптимизации работы библиотеки в целом.
Почему сейчас мы не изучаем Redux, стоит ли бросить все и прочитать другой туториал? Определенно - нет. Продолжайте изучение данного курса.
Ответ кроется :
Вообще state у компонентов используется не часто. С появлянием - подхода, коммьюнити стало перемещаться на сторону stateless подхода, когда state не используется вообще (за исключением редких моментов). Мой любимый игрок данного лагеря - Redux, о котором я тоже написал на русском.
с console.log'ами и обработчиком кликов на фразе "Всего новостей".