Автор оригинала: Chris Harrington.
Этот учебник RAGE.JS научит вам, как создать простое приложение TODO, используя Rection JS и архитектуру потока. Реагирование JS делает некоторые волны в сообществе, недавно из-за его предполагаемой производительности увеличивается по сравнению с другими тяжелыми фаворитами (например, угловые JS), особенно когда речь идет о написании списков. В результате я заинтересован в том, как написать приложение, которое легко использовать пользователю, одновременно быстрый, чтобы сойти с земли. Один из больших рисунков для реагирования JS является виртуальным домом, который находится за сценами для каждого представления, и это причина, по которой говорится, что реагируют так хорошо. Когда вид требует рерандера, все это сделано в виртуальную копию DOM. Как только это завершено, Rect выполняет различие между виртуальным домом и фактическим домом и применяет только изменения, которые указывают на сравнение уравнения diff.
Итак, что вы, надеюсь, собираетесь узнать к концу этой статьи? Вы поймете основы создания нескольких просмотров в реакции, вы увидите конкретный пример относительно того, как архитектура Flux предоставляет доступ к данным, а затем, наконец, вы увидите, как все это происходит вместе с простой приложением TODO.
Flux – это способ извлечения данных с вашего сервера API при сохранении строгих развязки компонентов на стороне вашего клиента. Это использует односторонний протокол связи, чтобы поддерживать разделение опасений. Приложение TODO использует Flux для получения данных из Mydiced API OUT Server.
Реагируйте JS и Flux идут вместе довольно хорошо, так как он был архиваторным, но они ни в коем случае не зависят друг от друга. В результате я собираюсь разделить эту статью в произведение React JS Piece, которая перейдет как создавать представления и лучшие практики, а затем подробный взгляд на то, как я получаю данные из My Mocked Server API через Поток.
Я поставил демонстрацию приложения TODO в действии, но приготовьтесь к разочарованию, так как это действительно очень просто. Если вы хотите проверить это, голова здесь Отказ Больше интереса может быть полный исходный код для приложения TODO, который я сделал доступным на Github. Проверьте это здесь Отказ
Реагировать js.
Во-первых, если вы никогда не слышали о Реагировать js Предполагается, что это визуализатор просмотра производительности, сделанный парнями Facebook. Многие из тяжеловесных соперников для MVVM Frameworks имеют трудное время, предоставляющее большое количество данных, как в списках и таких. Реагистрация не имеет этой проблемы, так как она делает только то, что изменилось. Например, если пользователь просматривает список из 100 элементов, отображаемых с помощью реагирования, и он или она каким-то образом меняет третий вниз, только этот пункт будет перенаправлен, оставив другие 99 предметов без изменений. Он также использует то, что Facebook вызывает «виртуальный DOM» для некоторой повышенной производительности, написав полный рендер практически, а затем проверяя разницу между виртуальным визуальным видом и что на самом деле на DOM и создает патч. Реагирование использует файлы JSX (необязательно) для записи представлений, что означает, что JavaScript и HTML могут жить в одном файле. Это немного сдвигаемой парадигмы и привыкается к. Вам не нужно использовать JSX для записи видов реагирования, но это намного проще, чем изначальное, какое компоненты для рендеринга, поэтому я предлагаю использовать его.
Рейкт работает от классов. Чтобы сделать какой-нибудь HTML, сначала вам нужно создать класс React, который описывает, что для рендеринга. Вот пример простого класса RACT.
var HelloWorld = React.createClass({ render: function() { returnHello, world!; } }); React.render(new HelloWorld(), document.body);
Во-первых, мы создаем наш класс React, называемый HellowOrld Отказ В нем мы указываем одну функцию: рендеринг. Это то, что вызывается, когда мы хотим рендер HTML внутри, как, например, на нижней линии фрагмента. Вы заметите, что функция рендеринга в нашем классе содержит HTML; Это где jsx вступает в игру. Это позволяет нам писать HTML внутри наших файлов JavaScript вместо того, чтобы поместить их в отдельные шаблоны. Последняя строка в фрагменте указывает на то, что мы хотим, чтобы наши HellowOrld класс для оказания в тело документа.
Реквизит
Итак, что происходит, когда мы хотим передать некоторые данные на наши классы Ract React? Пример выше не предусматривает какого-либо механизма для этого, но это делает.
var HelloWorld = React.createClass({ render: function() { returnHello, {this.props.name}!; } }); React.render(new HelloWorld({ name: "Chris Harrington" }), document.body);
Здесь мы представляем реквизит Аргумент в классе React, которые используются специально для передачи данных в просмотр реакций. Любые изменения в переменную PROP привернут реранду соответствующей части вида. Эти изменения могут прийти из самого просмотра или от родительского вида или любых дочерних взглядов, наш взгляд. Это довольно удобно, так как позволяет нам проходить некоторые данные между различными взглядами и все остаются в синхронизации. На фрагменте выше, я проезжаю во имя HellowOrld Класс, который отображается внутри DIV, используя переменную реквизиты.
Состояние
var HelloWorld = React.createClass({ getInitialState: function() { return { counter: 0 }; }, increment: function() { this.setState({ counter: this.state.counter+1 }); }, render: function() { return; } }); React.render(new HelloWorld(), document.body);{this.state.counter}
Этот фрагмент представляет другую часть класса React: Государство Отказ Государственная собственность класса React Project позволяет отслеживать внутренние изменения в представлении. Так же, как реквизиты, любые изменения в состоянии будут вызвать Rerender из соответствующих элементов, с одним условием: вы должны позвонить в SetState Метод, как видно в увеличение функция на классе. Всегда используйте SetState! Без этого ваши изменения не будут отражены на вашем представлении, что является всей точкой использования реагирования в первую очередь. Получающийся стадь Функция требуется при использовании внутреннего состояния. Это указывает на то, что должно быть первоначальное состояние. Обязательно включите эту функцию, даже если ваше состояние пусто для начала; Пустое состояние все еще является государством.
Итак, когда вы используете реквизит или состояние, или даже только частные переменные? Реквисы используются для передачи данных между ребенком и родительскими классами React, и любые изменения в предприниматель вызывают автоматическую рерандуку вида, как родителя, так и ребенка. Для данных, которые относятся только к просмотру и ничего другого, используйте состояние. Любые изменения здесь также переваривают вид. Для любых данных, которые относятся к классу, но не само по себе, вы можете использовать частную переменную, но я все равно, вероятно, использую состояние; Это то, что это за.
Вложенные виды
Одна из вещей, которая делает реагирование настолько простым в использовании, – это концепция гнездовых видов. Мы можем редить в реагированные классы из других классов реагирования, как таковые.
var FancyButton = React.createClass({ render: function() { return } }); var HelloWorld = React.createClass({ getInitialState: function() { return { counter: 0 }; }, increment: function() { this.setState({ counter: this.state.counter++ }); }, render: function() { return; } });{this.state.counter}
Здесь мы абстрагировали кнопку, чтобы увеличить счетчик в отдельный класс реагирования, проходящего в тексте, класс значка (через шрифт Awesome) и обработчик кликов. Это иллюстрирует, как реквизиты могут быть назначены через вложенные классы.
Примечание: Поскольку «CLASS» – это ограниченное слово в JavaScript, написание классов CSS на HTML-класса React Class осуществляется с помощью текста «ClassName». Вы можете увидеть, что в фрагменте выше, где я устанавливаю класс CSS для значка в FancyButton.
Пользовательские функции просмотра
Есть несколько других функций, которые вы должны знать при написании представлений реагирования.
- ComponentWillmount – Эта функция называется при добавлении представления на родительский вид. Он уволен каждый раз, когда это происходит, поэтому это хороший кандидат для выполнения некоторой первоначальной настройки вашего представления или для подключения обработчиков событий и такого. Это пригодится для реализации нашего флюсовой архитектуры позже.
- ComponentWillunmount – противоположность ComponentWillmount Отказ Уволен, когда вид больше не визутся в родительском. Полезно для отсоединения обработчиков событий.
Посмотрите на Реагирование документации JS Для полного списка методов вы можете реализовать.
Предопределенные функции просмотра
- SetState – Как уже упоминалось выше, это метод, который вы вызываете, чтобы установить внутреннее состояние вашего представления об реагировании. Если вы устанавливаете состояние напрямую (т. Е.) Ваше представление не будет Rerender. Как правило, всегда используйте STETSTATE, как таковой: this.setstate ({foo: “bar”}).
- ForceUpdate – Это удобный способ заставить рерандер зрения. Это полезно для экземпляров, в которых вы обновляете некоторые переменные внутри вашего представления, что не являются частью реквизита или состояния.
Есть и другие методы, которые вы можете использовать по мнению, но это два, которые я использовал больше всего. Для полного списка см. Реагирование документации JS Отказ Это основы реактивных js. Теперь я собираюсь перейти, как работает архитектура Flux, а затем мы перейдем к приложению Todo.
Поток
Архитектура Flux – это то, что Facebook рекомендует использовать в качестве рабочего процесса для извлечения данных на стороне клиента из магазина некоторых сортировков на удаленном сервере. Это однонаправленный поток данных. На высоком уровне пользователь инициирует действие, которое представление обрабатывает, отправляя запрос на данные в магазин. В свою очередь, этот магазин выполняет запрос и когда данные извлекаются, испускает событие, говорящее, что все, что слушают. Эти слушатели обновляют свои взгляды соответственно. Вот основные компоненты:
- Вид – Вид несет ответственность за обработку действий пользователем, например, извлечение списка товаров TODO. Это делает это, отправив запрос на данные через диспетчер.
Диспетчер – Диспетчер имеет два основных обязанности:
- Регистрация обратных вызовов после отправки. Магазин будет зарегистрировать обратный вызов с диспетчером так, чтобы всякий раз, когда действие будет отправлено, магазин уведомляется и может проверить, необходимо проверить, необходимо ли выполнять какие-либо действия. Например, реестры класса Toostore с диспетчером так, что всякий раз, когда отправляется действие для извлечения всех TODOS, он знает, что начнет процесс получения данных.
- Диспетку действий для выполнения. Представление отправляет действие для извлечения данных через метод Dispatch на диспетчере. Любые обратные вызовы, зарегистрированные с использованием того же ключа, получают уведомления о отправке. Метод Dispatch, как правило, содержит любую необходимую информацию полезной нагрузки тоже, например, например, идентификатор при получении определенного элемента данных.
Магазин – Магазин также имеет две обязанности.
- Просыпаться в соответствующей отправке для получения запрошенных данных. Это достигается через регистрацию с помощью диспетчера, как правило, при построении.
- Уведомление слушателей изменений в данных магазина после поиска, обновления или создания операции. Это делается через эмиттер события.
- Эмиттер событий – Эмиттер мероприятия отвечает за уведомление абонентов после того, как магазин завершил какие-либо действия. И наоборот, он также должен иметь возможность регистрировать наблюдателей для определенных событий. Мы собираемся использовать Emitter Emitter Node в приложении Todo.
Диспетчер
Диспетчер несет ответственность за принятие запросов на действие с точки зрения и передачу его на соответствующее магазино (или магазины). Каждый магазин будет зарегистрироваться с диспетчером для получения обновлений, когда действие будет отправлено. Конструктор для магазина регистрирует обратный вызов с диспетчером. Это означает, что всякий раз, когда действие будет отправлено, этот обратный вызов выполняется, но только действия, которые соответствуют этому диспетчеру, когда-либо выполняются. Пакет React Bower предоставляет класс диспетчера для нас для использования из коробки, поэтому для нас ничего не существует, к счастью. Диспетчер – это первый шаг в процессе доступа к данным на стороне клиента.
Магазин
Магазин используется для фактического извлечения, обновления или создания данных после прохождения действия, что указывает как таковое. Конструктор для хранилища будет подключаться к функции обратного вызова через метод реестра диспетчера, который предоставляет одностороннюю точку входа в магазин. Затем магазин проверяет, каков тип действия был отправлен и, если он применяется к этому магазину, выполняет соответствующий способ.
Пример
Вот быстрый и грязный пример относительно того, как Flux будет работать в образец реагирования на применение. Позже мы посмотрим в приложение Todo, которое будет погружаться в архитектуру потока немного больше.
var Count = React.createClass({ getInitialState: function() { return { items: [] }; }, componentWillMount: function() { emitter.on("store-changed", function(items) { this.setState({ items: items }); }.bind(this)); }, componentDidMount: function() { dispatcher.dispatch({ type: "get-all-items" }); }, render: function() { var items = this.state.items; return{items.length}; } }); var Store = function() { dispatcher.register(function(payload) { switch (payload.type) { case: "get-all-items": this._all(); break; } }.bind(this)); this._all = function() { $.get("/some/url", function(items) { this._notify(items); }.bind(this)); } this._notify = function(items) { emitter.emit("store-changed", items); }); }; var ItemStore = new Store();
Наш простой вид просто делает количество элементов в списке. На горе он крючки в Emitter событий, чтобы посмотреть, когда в магазине меняется, а затем отправляет запрос на получение всех элементов TODO. Магазин видит это, потому что в строке времени он регистрируется с диспетчером, чтобы посмотреть за запросы, чтобы получить все предметы. Когда запрос наступает, он выполняет быстрый запрос AJAX и когда это возвращает, уведомляет всех подписчиков через эмиттер события. Вернуться на вид, состояние обновляется новым списком элемента и ререндаторами View, показывающая обновленный счет.
Приложение TODO
Хорошо, теперь, когда у нас есть довольно хорошая ручка о том, как писать представления на реакцию и то, о чем вообще архитектура потока, мы собираемся взглянуть на образец приложения TODO, я написал специально для этого поста. Если вы хотите увидеть его в действии, GO здесь или если исходный код больше всего поднимает свой аллей, вы можете увидеть это здесь Отказ
Взгляды
Давайте начнем с главного взгляда. У приложения есть только одна страница, поэтому здесь она есть.
Делать
"use strict"; var Todo = React.createClass({ getInitialState: function() { return { todos: [] } }, componentWillMount: function() { emitter.on(constants.changed, function(todos) { this.setState({ todos: todos }); }.bind(this)); }, componentDidMount: function() { dispatcher.dispatch({ type: constants.all }); }, componentsWillUnmount: function() { emitter.off(constants.all); }, create: function() { this.refs.create.show(); }, renderList: function(complete) { return; }, render: function() { return
; } });Todo List
Incomplete
{this.renderList(false)}Complete
{this.renderList(true)}
Это главная Todo Посмотреть. На горе он отправляется запрос на все элементы TODO, которые должны быть получены. Он также подключается к событию изменения для хранения Todo, чтобы быть уведомленным, когда элементы магазина были обновлены после успешного завершения отправки запроса. Я использую сетку Bootstrap для отображения полных и неполных предметов. Здесь есть пара других классов, которые еще не отображаются: Список и Модал Отказ Первый для оказания фактического списка, а последний – добавить новый элемент.
Список
var List = React.createClass({ renderItems: function() { return _.map(this.props.todos, function(todo) { return- ; }); }, render: function() { return
-
{this.renderItems()}
В представлении списка отвечает за оказание списка элементов, как полных, так и неполных. Это руки от Предмет класс, чтобы сделать фактический товар.
Пункт
var Item = React.createClass({ toggle: function() { this.props.todo.isComplete = !this.props.todo.isComplete; dispatcher.dispatch({ type: constants.update, content: this.props.todo }); }, render: function() { return
Предмет Класс несет ответственность за две вещи: рендеринг элемента в списке и обновление статуса элемента при нажатии. Li Tag обладает обработчиком OnClick, который выходит из метода Toggle, который отправляет запрос элемента обновления через диспетчер. Диспетчерский элемент содержит два свойства: тип, чтобы указать имя события и содержимое, для указания полезной нагрузки события, которая в этом случае является самой объектом TODO.
Модаль
var Modal = React.createClass({ getInitialState: function() { return { value: "" }; }, componentDidMount: function () { this.$el = $(this.getDOMNode()); this.$el.on("hidden.bs.modal", this.reset); emitter.on(constants.changed, function() { this.$el.modal("hide"); }.bind(this)); }, componentWillUnmount: function() { emitter.off(constants.changed); }, show: function () { this.$el.modal("show"); }, reset: function() { this.setState({ value: "" }); }, save: function() { dispatcher.dispatch({ type: constants.create, content: { name: this.state.value, isComplete: false }}); }, onChange: function(e) { this.setState({ value: e.target.value }); }, render: function() { return; } });
Модальный класс – это … Verbose, но многие из которых требуется код Bootstrap, необходимый для модального диалога. Однажды это с пути, есть только три вещи, о которых мы действительно заботимся.
- Текстовый ввод – Вход текста предоставляет пользователю область для ввода имени для нового элемента. Привязка входных элементов к значению состояния является одним из предупреждений реагирования, которые я пойду за секунду.
- Кнопка сохранения – Кнопка «Сохранить» срабатывает метод сохранения, который отправляет действие создать действие с содержимым, установленным только на имя и свойство ISCOMPLETE (по умолчанию для false).
- Кнопка сброса – Кнопка RESET Button в способе сброса, который сбрасывает значение поля ввода, чтобы пользователь был представлен пустой коробкой ввода, когда он или она открывает диалоговое окно во второй раз.
Показать метод Модал Класс интересен здесь, потому что он подчеркивает Refs Свойство родителя, которое в этом случае является Todo класс. На Модал Определение, мы указываем Ref Атрибут («модальный»), который мы можем затем использовать для поиска визуализированного класса позже от родителя. Мы используем его, чтобы показать модальный диалог, когда пользователь нажимает на новую кнопку элемента на Todo класс.
Связывание данных
Привязка состояния представления на входе – это немного странный в реакции, по крайней мере, сначала. Если мы укажем, что текстовое поле имеет значение, как прочитанное из переменной состояния, нам также необходимо указать обработчик события Onchange для этого текстового поля. Если мы этого не сделаем, пользователь будет набран в тексте на текстовом поле, и текст не появится. Это связано с тем, что значение текстового поля связано с значением состояния, которое никогда не обновляется, и поэтому в поле зрения нет никаких изменений. Мы решаем эту проблему, установив обработчик OnChange, чтобы он обновил связанную переменную состояния, когда пользователь вводит информацию. Это небольшое предупреждение, которое бросило меня за петлю, когда я впервые начал писать открытыми реакцией.
Магазин
Вот магазин используется для отслеживания изменений в списке Todo.
var Store = function(url, constants) { this._url = url; this._collection = []; dispatcher.register(function(payload) { switch (payload.type) { case constants.all: this._all(); break; case constants.update: this._update(payload.content); break; case constants.create: this._create(payload.content); break; } }.bind(this)); this._all = function() { $.get(this._url).then(function(data) { this._collection = data; _notify.call(this); }.bind(this)); }.bind(this); this._update = function(content) { var found = _.find(this._collection, function(x) { return x.id === content.id; }); for (var name in found) found[name] = content[name]; $.post(this._url, found).then(function() { _notify.call(this); }.bind(this)); }; this._create = function(content) { content.id = _.max(this._collection, function(x) { return x.id; }).id + 1; this._collection.push(content); $.post(this._url + "/" + content.id).then(function() { _notify.call(this); }); }; function _notify() { emitter.emit(constants.changed, this._collection); } }; var TodoStore = new Store("fixtures/todos.json", require("constants").todo);
Сразу с BAT, в магазине регистрирует функцию обратного вызова с диспетчером для отслеживания любых отправленных действий. Как только действие вступит в действие, мы выполняем переключатель типа полезной нагрузки, чтобы определить, какой метод выполнить, затем выполнить метод. Как только все метод обновления или создания завершены, называется метод уведомления, который только что излучает событие изменений для любого прослушивания со списком элементов.
Константы
На протяжении всего приложения IDO я делаю ссылку на объект констант. Это просто объект, содержащий строки для каждого из различных действий, которые летают через диспетчер и эмиттер событий. Я считаю удобным держать эти строки абстрагированными в другом месте.
Заключение
Вот и все! Как я уже упоминал выше, если вы хотите увидеть приложение TODO в действии, посмотрите здесь И если вы заинтересованы в проверке кода для себя, посмотрите здесь Отказ Спасибо за прочтение!