bidirecional flux: o fim do data-binding - qconsp · 2016-08-26 · two-way-binding november, 2nd,...

Post on 30-May-2020

1 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Oliver Häger

Contexto Onde encaixa o tópico

Cont

exto

‘Novo’ paradigma: Orientado ao componentes

Cont

exto

polymer

angular2

aurelia

react

flight

Cont

exto

Mostrar custom elementvar ShopApp = React. createClass({ render: function () { return ( <BasePage> <div className="grid"> <div className="grid__cell grid__cell" > <ShopMenu mountto="#shopcanvas" /> </div> </div> <div className="grid"> <div className="grid__cell grid__cell--width-70" > <div id="shopcanvas"> <ProductContainer/> </div> </div> <div className="grid__cell grid__cell" > <CartContainer/> </div> </div> </BasePage> ) }});

React Example

Cont

exto

ObjetivoAlguem disse “Flux”?

Obj

etiv

o

Flux é um padrão arquitetural para estabelecer fluxo de dados unidirecional entre componentes.

Obj

etiv

o

whY?

Obj

etiv

o

Flux (by Facebook)

Obj

etiv

o

Entenda porque há necessidade de um conceito como Flux no mundo de aplicativos web baseados em componentes.

Two-way-bindingExcurso: Uma técnica desvanecendo

Two-

way

-bin

ding

Two-

way

-bin

ding

Comfortável, mas caro:- Verificar modelos complexos- Verificar muitos modelos

Two-

way

-bin

ding

Rastreamento do modelo- Ciclo de monitoramento

- p.e. Digest-cycle ($apply)

- Algoritmo de comparação- p.e. JSON.stringify(), ou

percorrer propriedades manualmente

Two-

way

-bin

ding

Object.observe()?(funcão nativa para monitoramento de objetos)

Two-

way

-bin

ding

November, 2nd, 2015

https://esdiscuss.org/topic/an-update-on-object-observe

Two-

way

-bin

ding

November, 2nd, 2015

After much discussion with the parties involved, I plan to withdraw the Object.observe proposal from TC39 (where it currently sits at stage 2 in the ES spec process), and hope to remove support from V8 by the end of the year (the feature is used on 0.0169% of Chrome pageviews, according to chromestatus.com).

https://esdiscuss.org/topic/an-update-on-object-observe

Two-

way

-bin

ding

Mostrar custom elementvar TwoWay = React. createClass({ getInitialState : function() { return {message: this.props.message}; },

componentWillReceiveProps : function(nextProps){ if(this.state.message !== nextProps. message){ this.setState({message: nextProps.message}); } },

handleChange: function(event) { this.setState({message: event.target.value});

if(this.props.onChange){ this.props.onChange(event);

} }, render: function() { var message = this.state.message; return <input type="text" value={message} onChange={this.handleChange} />; }});

React Two-Way-Binding

Two-

way

-bin

ding

2. Fluxo unidirecional Uma abstração evolutiva

Abs

traç

ão

Abs

traç

ão

Mostrar custom elementvar ShopApp = React. createClass({ render: function () { return ( <BasePage> <div className="grid"> <div className="grid__cell grid__cell" > <ShopMenu mountto="#shopcanvas" /> </div> </div> <div className="grid"> <div className="grid__cell grid__cell--width-70" > <div id="shopcanvas"> <ProductContainer/> </div> </div> <div className="grid__cell grid__cell" > <CartContainer/> </div> </div> </BasePage> ) }});

React Example

Abs

traç

ão

Data Binding entre componentes

Abs

traç

ão

Mostrar custom elementvar ProductListContainer = React. createClass({

getInitialState : function(){ return {products : []} },

onProductsChanged : function(products){ this.setState( {products : products}); if(this.props.onChanged){ this.props.onChanged(products) ; } },

componentWillMount : function(){ ShopService. loadProducts().then(this.onProductsChanged ); },

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

React Example

Abs

traç

ão

Data Binding com componentes

Abs

traç

ão

Data Binding com componentes

Abs

traç

ão

Propagação de dados entre os componentes é complexo e não escala

Usar eventos não resolve pois também não escala

Abs

traç

ão

Extrair o estado para fora dos componentesA

bstr

ação

O Store mantem modelos, sabe atualizá-los e notifica os componentes

Abs

traç

ão

Mostrar custom element

var shopStore = FooFlux. createStore({ id : 'shopStore', _products : [], getProducts : function(){

return _.cloneDeep(this._products); }, addProduct : function(product){ this._products.push(product); this.notify(); }, loadProducts : function(){

ShopService.loadProducts().then(function(products){ this._products = products; this.notify();}.bind(this));

}});

Code

Abs

traç

ão

Abs

traç

ão

O Dispatcher delega as atualizações para todos os Stores

Abs

traç

ão

Mostrar custom elementvar shopStore = FooFlux. createStore({ id : 'shopStore', _products : [], getProducts : function(){

return _.cloneDeep(this._products); }, addProduct : function(product){ this._products.push(product); this.notify(); }, loadProducts : function(){

// ... }});

FooFlux.getDispatcher().register(function(actionName, data) { switch (actionName) { case 'addProduct': shopStore. addProduct(data); break; case 'loadProductList' : shopStore. loadProducts(); break; }});

Code

Abs

traç

ão

A Action expressa a intenção semanticamente e a passa para o Dispatcher

Abs

traç

ão

Mostrar custom elementFooFlux.getDispatcher().register(function(actionName, data) { switch (actionName) { case 'addProduct': shopStore. addProduct(data); break; case 'loadProductList' : shopStore. loadProducts(); break; }});

var shopActions = FooFlux.createActionCreator({ id: 'shopActions', addProduct : function(product){ // propagate to Store via Dispatcher FooFlux.getDispatcher().dispatch('addProduct', product); }, loadProductList : function(){

FooFlux.getDispatcher().dispatch('loadProductList' ); }});

Code

Abs

traç

ão

SimplificandoA

bstr

ação

Abs

traç

ão

Abs

traç

ão

Mostrar custom elementvar ProductListContainer = React. createClass({

getInitialState : function(){ return {products : []} },

onProductsChanged : function(products){ this.setState( {products : products}); if(this.props.onChanged){ this.props.onChanged(products) ; } },

componentDidMount : function(){ ShopService. loadProducts().then(this.onProductsChanged ); },

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

React Example- Anterior

Abs

traç

ão

Mostrar custom elementvar ProductListContainer = React. createClass({

getInitialState : function(){ return {products : ShopStore.getProducts()} },

onProductsChanged : function(){ this.setState( {products : ShopStore.getProducts() }); },

componentDidMount : function(){ ShopStore. addChangeListener (this.onProductsChanged ); ShopActions.loadProducts(); },

componentWillUnmount : function(){ ShopStore. removeChangeListener (this.onProductsChanged ); },

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

React Example - Com Flux

Abs

traç

ão

Simplifica o fluxo de dados

Escala com a complexidade

Separação de conceitos

Desacoplamento

Conc

lusã

o

R.I.P. 2-way-binding?

Conc

lusã

o

Não!

Conc

lusã

o

Não!

*Dentro* de um componente é viável e até necessário, mas deve ser utilizado com cautela.

Conc

lusã

o

Não!

Os frameworks modernos continuam a usar/suportar two-way-binding.

Hoje o conceito é bem entendido eexistem várias implementações

Conc

lusã

o

Facebook Flux https://facebook.github.io/flux/Alt.js http://alt.js.org/Fluxible http://fluxible.io/NanoFlux https://github.com/ohager/nanofluxetc pp

Variações de Flux original

Conc

lusã

o

NanoFluxhttps://github.com/ohager/nanoflux

Refluxhttps://github.com/reflux/refluxjs

Redux http://redux.js.org/“Predictable Application State Container”

- Único Store (unindo Dispatcher e Action Creator)

- Usar funcões (“Reducers”) para alteração de Status

oliver@devbutze.comoliver.hager@dextra-sw.com

https://br.linkedin.com/in/oliverhager

Thnx!Questions!

top related