ОБНОВЛЕНИЕ 2018: в учебнике хорошая теория, но ему уже два года. Проверяйте версии пакетов. За выходом нового учебника можно следить в или
На так же проводятся бесплатные вебинары, публикуются переводы и авторские материалы, !
Добавить новость
Что такое добавление новости?
Это форма, в которую мы вводим необходимые данные.
Это "лента новостей", которая отображает наши данные.
После создания новости должно генерироваться событие, на которое должна быть подписана новостная лента. Иначе, как лента узнает о том, что нужно показать новую новость?
Очевидно, что нам нужна какая-то "система событий", чтобы научить компонент <Add /> генерировать событие, а компонент <News /> отображать. Так как компонент <News /> имеет статичный атрибут data, было бы логично предположить, что в data нужно "скидывать" динамически сформированную переменную. Конечно же, это место где нужно использовать state.
Подытожим:
компонент <App /> должен иметь переменную в state - "новости", которую передавать в компонент <News />.
Компонент <App /> должен уметь слушать событие "добавлена новость".
Компонент <App /> так же должен уметь отписываться от прослушивания события.
Мы добавили переменную в state (с начальным состоянием новостей - массивом my_news), ее же стали передавать в качестве свойств, для компонента <News />. А также, "как будто подписались" на прослушивание события в момент примонтирования компонента, и "как будто отписались" в момент "перед удалением компонента". В нашем примере, компонент <App /> не может быть удален, но тем не менее "не забывать отписываться" - хорошая практика.
На втором берегу, у нас компонент <Add />, который должен уметь генерировать событие в обработчике onBtnClickHandler.
Кстати, переименуйте кнопку "показать alert" -> "Добавить новость", так как мы уже почти готовы!
Глобальная система событий
Напомню, у нас возник вопрос о необходимости взаимодействия двух компонентов. Эти компоненты не состоят в отношении родитель-потомок.
window.ee.addListener - принимает в качестве аргументов имя события и функцию-обработчик. Чтобы внутри функции-обработчика (callback) использовать this - мы сохранили его чуть выше в переменную self.
Интересный момент: var nextNews = item.concat(self.state.news);
Мы создали новый массив, в котором первым элементом поставили новую новость, чтобы она была верхней в списке.
Кстати, было бы неплохо частично очищать форму после добавления новости: а именно, удалять текст новости, но оставлять "чекбокс" и автора. Внесите эти изменения в onBtnClickHandler:
...
onBtnClickHandler: function(e) {
e.preventDefault();
var textEl = ReactDOM.findDOMNode(this.refs.text);
var author = ReactDOM.findDOMNode(this.refs.author).value;
var text = textEl.value;
var item = [{
author: author,
text: text,
bigText: '...'
}];
window.ee.emit('News.add', item);
textEl.value = '';
this.setState({textIsEmpty: true});
},
...
Удобно, что кнопка "дизейблится" (disable) после очистки.
Ужасно длинный файл. Так хочется разбить его на кусочки, использовать ES6 синтаксис, модули, сжимать его в конце-концов...
Не торопите события! На данный момент было важно показать вам именно работу с реактом, как с "просто еще одной библиотекой". Организация кода "на современный лад" - входит в мои планы. Быть может, когда вы будете читать этот текст, соответствующая глава уже будет написана.
Итого: Мы научили компоненты совместной работе. Посмотрели на реализацию EventEmitter для браузера.
Данный урок хорош тем, что он показывает подход к реализации глобальной системы событий в React.js
Предлагаю воспользоваться решением , для этого скачайте/добавьте (.min ) в index.html, перед app.js.
Полезная ссылка по вопросу организации взаимодействия между компонентами
Мне очень симпатичен Redux, который элегантно решает эту проблему. По нему тоже есть . Рекомендую к изучению.