Качества хорошего Flux Реализации

Это был захватывающий год для моей команды.В прошлом году мы стартовал проект, используя React 3 1 , и в течение проекта we’ ве узнал много нового о Реагировать и Flux 2 — Facebook’ ы рекомендуется архитектурные принципы Реагировать приложений.В этой статье, we’ возьму взглянем на некоторые из ключевых уроков, we’ ве узнал .

Ли you’ новичок реагировать и Flux, или собирается, насколько создать свой собственный Flux реализации, я думаю, you’ будете не только наслаждаться это путешествие с нами, но найти некоторые пищу для размышлений вопросы и wisdom Вы можетеприменять в своих начинаниях .

Полезная Background

Это сообщение предполагает, что вы есть некоторый уровень знакомства с Реагировать и поток.Уже знакомый с ними?Не стесняйтесь, чтобы пропустить “ Введение | Lux.js__85 раздел.В противном случае, я рекомендую прочитать ниже .

React

React 3 1 является открытым исходным кодом Java-библиотека, поддерживается в основном Facebook, и предназначен для использования в больших приложений, использующих данные, что изменения с течением времени,Очевидно, что это особенно полезно при разработке одностраничный applications.Если you’ уже знакомы с модель-представление-controller узором, реагировать считается только view, обработки интерфейс пользователя в приложении, и может быть использован в сочетании с другими библиотеками JavaScript или большего MVCрамки.Here’ S высокого Резюме Уровень Реакция:

  • Реагировать фокусируется на | view__42 проблем, и не пытайтесь быть “ все framework”
  • Реагировать интерфейсов построены из компонентов .
  • Реагировать компоненты могут быть написаны с использованием JSX __56 | 4 — расширение XML на основе JavaScript, чтобы — или с простым JavaScript .
  • Реагировать компоненты оказывают виртуальной DOM.После Штукатурки “ diffed” с предыдущей визуализации, и минимальное количество DOM мутаций выполняются эффективно залатать DOM, чтобы довести его до даты .

Выезд Facebook’ с Получение Started 5 руководство .

Flux

Flux 6 является Архитектурный pattern по Facebook рекомендуется для создания приложений с React.В то время как React’ з мнений nudge Вы к однонаправленным потоком данных, поток обеспечивает более полную картину относительно того, что, что actually выглядит.Несколько Flux реализации возникли (LeanKit’ с lux.js 7 , входит в комплект), обеспечивая захватывающее представление о том, как разные команды решают стоящие перед ними задачи.Резюме высокого уровня Flux будет включать:

  • Flux приложения имеют три основные абстракции: вид (Реагировать компоненты), магазины и диспетчер .
  • Просмотров “ propagate” действия (например, взаимодействие с пользователем) через диспетчер .
  • Диспетчер обрабатывает уведомления различные магазины действия .
  • Если store’ изменяется состояние, он испускает событие изменения, и вид в зависимости от этого магазина для государства будет rerender .

Выезд Facebook’ ы | __27 обзор Flux __29 | 8 .

Введение Lux.js

Разработчики JavaScript провернуть новые рамки, как быстро, как политик делает обещания на предвыборном митинге.Почему же тогда, написать еще рамки?Я люблю эту тему, хотя это выходит за рамки данной статьи. Lux.js 9 является реализация Flux architecture использованием Реагировать;we’ ве учетом его под наш team’ специфичный набор потребностей, навыков и целей.На самом деле, наша работа с лк пытается тонкий баланс между последовательных мнений и гибкости, чтобы включить другие библиотеки, которые лучше всего решать проблему в руки .

Со временем, при отсутствии и успеха в очень немногих проектов, we’ ве нашли следующие качества, чтобы быть драйверы успеха в нашей собственной реализации потока:

  1. Don’ т получить в React’ S способ .
  2. Постоянно устранить макет .
  3. Обращайтесь с каждым вход как действие .
  4. Операции магазин must синхронными .
  5. Сделать это легко играть хорошо с не-люкс / не реагировать случаи .

Examples

Дмитрий Voronianski создано потока comparison __67 | 10 | __2, которая позволяет увидеть бок о бок comparison нескольких потоков вариантов (используя базовый торговый пример ВОЗ).I’ ве реализован тот же пример с использованием люкс, чтобы проиллюстрировать объяснения по пути.Я очень рекомендую проверить этот проект из — it’ са отличный способ быстро ознакомитьсясами с несколькими ведущими реализаций Flux .

ОК, и все, что из Кстати, let’ посмотрим поближе на качествах, которые я упоминал выше .

Оставаясь в Way

Реагировать делает большую работу при фокусировке только на то, что она направлена ​​на решение.Не будучи предписывающим по более широким вещи, как отдаленных передачи данных (HTTP, WebSockets), а также путем предоставления крючки, которые позволяют включать не реагировать библиотеки пользовательского интерфейса, реагировать дает возможность собрать средства, которые лучше всего удовлетворять потребности вашего приложения.Так же, как реагировать пребывания в сторону опасений, что doesn’ т решить для, we’ ве нашли it’ S менее важно держаться подальше от React’ ы образом.It’ Легко попасть в пути, как вы начнете абстрагируясь общий patterns в том, как вы используете другой библиотека / рамки позади вашего собственного API.(Примечание: это isn’ т всегда плохо) Например, let’ посмотрим на общие поведения компонентов we’ ве построен в люкс, и как наша использование из них эволюционировали .

Контроллер Views

Вы часто будет слышать React разработчики называют контроллер views — React компонент, который, как правило, находится на или вблизи верхней части раздела страницы, который слушает одного или нескольких хранилищ для изменения их состояния.Как магазины выделяют события изменения, обновления представлений контроллеров с новым государством и проходит изменений вплоть до его children с помощью реквизита .

Лк обеспечивает controllerView метод, который дает вам обратно Реагировать компонент, способный слушать люкс магазинов.Под капотом, люкс использует Mixins дать Реагировать компоненты различных типов поведения, и controllerView метод дает компонент как в store подмешать (что делает его способным слушать магазинах), и ActionCreator примесь (что делает его способным изданиядействия).Например:

var CartContainer = lux.controllerView({

  getActions: [ "cartCheckout" ],

  stores: {
    listenTo: [ "cart" ],
    onChange: function() {
      this.setState(getStateFromStores());
    }
  },

  getInitialState: function () {
    return getStateFromStores();
  },

  onCheckoutClicked: function () {
    var products = this.state.products;
    if (!products.length) {
      return;
    }
    this.cartCheckout(products);
  },

  render: function () {
    return (
      <Cart products={this.state.products} total={this.state.total} onCheckoutClicked={this.onCheckoutClicked} />
    );
  }
});

В то время как мы все еще как этот удобный подход, we’ ве оказались перехода к альтернативным подходом в создании равнину Реагировать компонент и, пройдя ЛЮКС Mixins, необходимые для достижения того же результата.Обратите внимание, что здесь we’ Re вызова React.createClass и используя mixins вариант:

var CartContainer = React.createClass({

  mixins: [ lux.reactMixin.store, lux.reactMixin.actionCreator ],

  getActions: [ "cartCheckout" ],

  stores: {
    listenTo: [ "cart" ],
    onChange: function() {
      this.setState(getStateFromStores());
    }
  },

  // other methods, etc.
});

Либо подход справедлив, хотя мы считаем, второй подход является более из React’ ы образом.Почему

  • Мы получаем component’ S displayName бесплатно (как трансформатор JSX будет использовать наш var имя, когда он видит React.createClass) .
  • Некоторые виды контроллер don’ т должны быть ActionCreators.Второй подход означает, что мы могли только пройти store подмешать в тех случаях сохраняя обеспокоенность ориентированные.Первый подход всегда дает компонентов как Mixins, даже если не используется .
  • There’ S Нет необходимости явно передавать Реагировать экземпляр Lux (сделано с помощью lux.initReact( React )), так что он знает, как создать компоненты .

Примечание: Зачем тратить время на объяснение этих двух различных подходов?It’ ы о пребывании из React’ ы образом.Мы можем легко стать жертвой либо пере- или underabstracting, таким образом, мы должны датьсами номера, чтобы адаптироваться в наше понимание улучшается.Эволюция нашего подхода с течением времени был проинформирован we’ ве спросил себя, что делает хорошую реализацию потока.Этот процесс постоянно допроса и оценки является жизненно важной частью жизни любой библиотеке или рамки .

Шаблонный Elimination

В нашем опыте, принимая Реагировать и поток переместился инфраструктуры и рамочные проблем в фоновом режиме, так мы можем сосредоточиться на на самом деле создания возможностей для нашего app.Тем не менее, есть досадные биты кода, которые, как правило, возникают много.Например, рассмотрим этот общий подход к проводке / unwiring компоненты слушать на события изменения магазин:

// Taken from the facebook-flux example:
// https://github.com/voronianski/flux-comparison/blob/master/facebook-flux/js/components/CartContainer.jsx
var CartContainer = React.createClass({
  // only showing the methods we're interested in

  componentDidMount: function () {
    CartStore.addChangeListener(this._onChange);
  },

  componentWillUnmount: function () {
    CartStore.removeChangeListener(this._onChange);
  },

  // more methods, etc.
});

Честно говоря, шаблонный налог isn’ т высокого здесь, но it’ S по-прежнему присутствует.Так Mixins может обеспечить методы жизнь компонент цикла, мы сделали это автоматически, когда вы включаете люкс- Mixins:

var ProductsListContainer = React.createClass({

  mixins: [ lux.reactMixin.store ],

  stores: {
    listenTo: [ "products" ],
    onChange: function() {
      this.setState(getAllProducts());
    }
  },

  // more methods, etc.
});

Когда наши ProductsListContainer встает, он будет готов слушать любой из пространства имен магазина, предусмотренных в stores.listenTo массив, и эти подписки будут удалены, если компонент Размонтирует.Прощай шаблонного

ActionCreator Boilerplate

В Flux приложений, you’ будете обычно видеть специальные модули ActionCreator как это:

// snippet from: https://github.com/voronianski/flux-comparison/blob/master/facebook-flux/js/actions/ActionCreators.js
var ActionsCreators = exports;

ActionsCreators.receiveProducts = function (products) {
  AppDispatcher.handleServerAction({
    type: ActionTypes.RECEIVE_PRODUCTS,
    products: products
  });
};

ActionsCreators.addToCart = function (product) {
  AppDispatcher.handleViewAction({
    type: ActionTypes.ADD_TO_CART,
    product: product
  });
};

Как мы регулярно спросил, что повторное код, который мы могли бы устранить и заменить конвенции, ActionCreator интерфейсы подходили.В нашем случае, мы используем postal.js 11 для связи между ActionCreators и диспетчера (почтовый является библиотека шины сообщений в памяти, обеспечивая передовые публикации / подписки функциональность).99,9% времени, метод ActionCreator опубликовал сообщение действий без дополнительного поведения.Вещи развивались с течением времени, как это:

// The very early days
// `actionChannel` is a ref to a postal channel dedicated to lux Actions
var ActionCreators = {
  addToCart: function() {
    actionChannel.publish( {
      topic: "execute.addToCart",
      data: {
        actionType: ActionTypes.ADD_TO_CART,
        actionArgs: arguments
      }
    } );
  }
};

Это было очень быстро абстрагироваться в ActionCreator примесь для того, чтобы это:

// The early-ish days
var ActionCreators = lux.actionCreator({
  addToCart: function( product ) {
    this.publishAction( ActionTypes.ADD_TO_CART, product );
  }
});

| You__30 заметите две вещи в коде выше: во-первых, использование lux.actionCreator, который смешивает lux.mixin.actionCreator в цель;во-вторых, publishAction Метод (предоставляется примесь) .

В то же время мы использовали выше подход подмешать, we’ г упала в практику, имеющие соответствующие имена, обработчик на наших магазинах (имя метода обработчика соответствует тип действия).Например, here’ са люкс магазин, который обрабатывает addToCart действия:

var ProductStore = new lux.Store( {

  state: { products: [] },

  namespace: "products",

  handlers: {
    addToCart: function( product ) {
      var prod = this.getState().products.find( function( p ) {
          return p.id === product.id;
      } );
      prod.inventory = prod.inventory > 0 ? prod.inventory - 1 : 0;
    }
  },

  // other methods, etc.
} );

Имена типа соответствия действий и имена обработчиков магазин сделал обычный провод планом очень просто, но мы видели другую область, где мы могли бы устранить макет: если 99% наших реализаций API ActionCreator только что опубликовал сообщение, то почему бы не вывести создание ActionCreator API, основанныйна то, что получает обрабатываются магазинах?Так мы и сделали, в то время как все еще позволяя пользовательские реализации методов ActionCreator где это необходимо.Например, когда экземпляр магазин в фрагменте выше создается, люкс увидите, что он работает в addToCart действия.Если ActionCreator APIhasn’ т уже определены для этой деятельности в рамках lux.actions, люкс будет создать, с поведением по умолчанию опубликования сообщение действий .

Принимая этот подход означает, что наши компоненты могут указать, что ActionCreator методы, которые они хотят в а-ля-карт стиле.В следующем фрагменте, наша ProductItemContainer использует lux.reactMixin.actionCreator подмешать, которая ищет getActions массив, и предоставляет указанные действия как методы на высшем уровне по компоненту.Вы можете увидеть we’ Re используя addToCart метод ActionCreator в onAddToCartClicked метода обработчика .

var ProductItemContainer = React.createClass({

  mixins: [ lux.reactMixin.actionCreator ],

  getActions: [ "addToCart" ],

  onAddToCartClicked: function () {
    this.addToCart(this.props.product);
  },

  render: function () {
    return (
      <ProductItem product={this.props.product} onAddToCartClicked={this.onAddToCartClicked} />
    );
  }
});

Как с любой конвенции, есть компромиссы.Состав является важным аспектом ActionCreator API.Они должны быть смоделированы отдельно от компонента (ов) , которые используют их.Пока мы считаем, что подход поддерживает, что, в то время как торговля некоторые из явного характера (например, сохраняя ActionCreators в своем собственном модуле) для гибкости и лаконичностью .

Все ли Action

Так как это поведение обеспечивая ActionCreator API, была отведена в примесь, он сделал это возможным для обоих Реагировать компонентов, а также не-люкс / Реагировать экземпляров использовать подмешать.Моя команда была пользуясь этим, когда дело доходит до вещей, как удаленных интерфейсов передачи данных.We’ Re используя гипермедиа клиента под названием halon 12 | __15, который понимает, как потреблять наши гипермедиа ресурсы, используя расширенную версию HAL 13 | __15 (гипермедиа приложений Язык, открытая спецификация для определения структуры HTTP ресурсов).Покрытие гипермедиа выходит за рамки данной статьи, но количество good 14 resources 15 exist 16 если you’ заинтересованы в получении дополнительной информации.Наш клиент-сторона обертка для хладона использует lux’ S actionCreator и actionListener Mixins так, что он может не только публиковать действия, но также обрабатывать их .

Мы подходим это так, потому что мы считаем, каждые input — будь то вход пользователя или очередь асинхронное выполнение (с помощью Ajax, PostMessage, WebSockets, и т.д.) — должны быть поданы в качестве клиента action.Если you’ ве ногу с любой из Реагировать обсуждений в течение долгого времени, Вы могли бы думать, “ Джим, Facebook ОК с вызовом отправки непосред …

Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров

Comments are closed.