Upgrade to Pro — share decks privately, control downloads, hide ads and more …

From MVC to Flux (v3)

From MVC to Flux (v3)

Explaining the motivation behind Facebook's Flux by
- outlining problems with MVC when scaling to larger apps
- describing how to restrict general MVC and how to arrive at Flux eventually
- share own impression/experience when working with Flux and give a short overview of common Flux libraries

Julian Viereck

June 05, 2015
Tweet

More Decks by Julian Viereck

Other Decks in Programming

Transcript

  1. Hi! Julian Viereck
 @jviereck • Open Source since 2009 •

    Studies CS @ ETHZ • Marathon Runner,
 Swimmer • 2013: Google Intern in Munich • Next: Facebook Internship
  2. “Flux, Flux, Flux: 
 Definitely a hot topic but I

    heard it is
 hard to get your head around it” - by a Zurich web developer
  3. - Edsger Dijkstra “The art of programming is the art

    
 of organizing complexity, […]
 and avoiding its bastard chaos 
 as effectively as possible.”
  4. Data Controller View Data Controller View Data Controller View Spaghetti

    
 App = What’s the problem? “M” “V” “C”
  5. Data Controller View Data Controller View Data Controller View Spaghetti

    
 App = ① Many different paths 
 What’s the problem? “M” “V” “C”
  6. Data Controller View Data Controller View Data Controller View “M”

    “V” “C” Spaghetti 
 App = What’s the problem? ① Many different paths 

  7. Data Controller View Data Controller View Data Controller View “M”

    “V” “C” Spaghetti 
 App = What’s the problem? ① Many different paths 

  8. Data Controller View Data Controller View Data Controller View “M”

    “V” “C” Spaghetti 
 App = What’s the problem? ① Many different paths 

  9. Data Controller View Data Controller View Data Controller View “M”

    “V” “C” Spaghetti 
 App = What’s the problem? ① Many different paths ② Cascading updates /
 Side effects
  10. Data Controller View Data Controller View Data Controller View “M”

    “V” “C” Spaghetti 
 App = What’s the problem? ① Many different paths ② Cascading updates /
 Side effects
  11. Data Controller View Data Controller View Data Controller View “M”

    “V” “C” Spaghetti 
 App = What’s the problem? ① Many different paths ② Cascading updates /
 Side effects
  12. Data Controller View Data Controller View Data Controller View “M”

    “V” “C” Spaghetti 
 App = What’s the problem? ① Many different paths ② Cascading updates /
 Side effects Small App App Complexity
  13. Data Controller View Data Controller View Data Controller View “M”

    “V” “C” Spaghetti 
 App = What’s the problem? ① Many different paths ② Cascading updates /
 Side effects Small App Large App App Complexity
  14. Data Controller View Data Controller View Data Controller View “M”

    “V” “C” Spaghetti 
 App = What’s the problem? ① Many different paths ② Cascading updates /
 Side effects Small App Large App App Complexity Manageable by
 Developer
  15. http://animalia-life.com/ Scaling in Nature circulatory system veins and arteries Not

    Scaleable Scaleable www.informatiquegifs.com/, Insects Mammals vs
  16. http://animalia-life.com/ Scaling in Nature circulatory system veins and arteries Not

    Scaleable Scaleable www.informatiquegifs.com/, Insects Mammals unrestricted restricted vs
  17. What’s the problem? ① Many different paths ② Cascading updates

    /
 Side effects Small App Large App App Complexity Manageable by
 Developer What’s the solution?
  18. What’s the problem? ① Many different paths ② Cascading updates

    /
 Side effects Small App Large App App Complexity Manageable by
 Developer Large App =
 3 x Small App What’s the solution?
  19. What’s the problem? ① Many different paths ② Cascading updates

    /
 Side effects Small App Large App App Complexity Manageable by
 Developer Large App =
 3 x Small App What’s the solution?
  20. What’s the problem? ① Many different paths ② Cascading updates

    /
 Side effects Small App Large App App Complexity Manageable by
 Developer Large App =
 3 x Small App What’s the solution? How?
  21. How to keep a city clean? By passing a law

    to disallow littering. Enforce the law. - and -
  22. How to keep a city clean? By passing a law

    to disallow littering. Enforce the law. - and - NOTE: Better way - teach everyone benefits of not littering and life in a better world :)
  23. Data Controller View Data Controller View Spaghetti 
 App FLUX

    RestrictionS ① Information flows in one direction ② Only Single Action at any point in time Flux App ?
  24. Data Controller View Data Controller View ObservationS • Controller only

    controls the data • Data only controls the views
  25. Data Controller View Data Controller View ObservationS • Controller only

    controls the data • Data only controls the views 㱺 Introduce Stores = App State +
 Business Logic Controller + Data
  26. Data Controller View Data Controller View ObservationS • Controller only

    controls the data • Data only controls the views 㱺 Introduce Stores = App State +
 Business Logic 㱺 Store Controller + Data
  27. Data Controller View Data Controller View Store View Store View

    Data Controller View Data Controller View
  28. Store View Store View Data Controller View Data Controller View

    Open Issue: How to prevent cascading updates? App Flipper Game!
  29. Store View Store View Data Controller View Data Controller View

    Open Issue: How to prevent cascading updates? Solution: Express updates explicit via Actions,
 add Gate Keeper App Flipper Game!
  30. Store View Store View Dispatcher Solution: Express updates explicit via

    Actions,
 add Gate Keeper ② Only Single Action at any point in time
 (asserted by Dispatcher Implementation) FLUX RestrictionS Action Action
  31. Flux App RestrictionS ① Information flows in one direction ②

    Only Single Action at any point in time Store View Store View Action Dispatcher
  32. Flux App RestrictionS ① Information flows in one direction ②

    Only Single Action at any point in time Store View Store View Action Dispatcher Server
  33. Flux App RestrictionS ① Information flows in one direction ②

    Only Single Action at any point in time Store View Store View Action Dispatcher Server Action
  34. Flux App RestrictionS ① Information flows in one direction ②

    Only Single Action at any point in time Store View Store View Action Dispatcher Q:
 Do you want
 to write tests
 for this? Server Action
  35. Flux App Store View Store View Action Dispatcher Data Controller

    View Data Controller View Spaghetti 
 App
  36. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store
  37. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store Performs
 XHR request
  38. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store Action { type: “FILE_REQ_BEGIN”, payload: { fileName: “foo.js” } } Performs
 XHR request
  39. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store Action { type: “FILE_REQ_BEGIN”, payload: { fileName: “foo.js” } } Performs
 XHR request
  40. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store { type: “FILE_REQ_BEGIN”, payload: { fileName: “foo.js” } } Performs
 XHR request
  41. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store { type: “FILE_REQ_BEGIN”, payload: { fileName: “foo.js” } } Performs
 XHR request
  42. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store { type: “FILE_REQ_BEGIN”, payload: { fileName: “foo.js” } } Performs
 XHR request
  43. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store { type: “FILE_REQ_BEGIN”, payload: { fileName: “foo.js” } } Performs
 XHR request XHR response
  44. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store { type: “FILE_REQ_BEGIN”, payload: { fileName: “foo.js” } } { type: “FILE_REQ_SUCCESS”, payload: { fileName: “foo.js”,
 content: “I <3 MJS!” } } Performs
 XHR request XHR response
  45. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store { type: “FILE_REQ_BEGIN”, payload: { fileName: “foo.js” } } { type: “FILE_REQ_SUCCESS”, payload: { fileName: “foo.js”,
 content: “I <3 MJS!” } } Performs
 XHR request XHR response
  46. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store { type: “FILE_REQ_BEGIN”, payload: { fileName: “foo.js” } } { type: “FILE_REQ_SUCCESS”, payload: { fileName: “foo.js”,
 content: “I <3 MJS!” } } Performs
 XHR request XHR response
  47. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store { type: “FILE_REQ_BEGIN”, payload: { fileName: “foo.js” } } { type: “FILE_REQ_SUCCESS”, payload: { fileName: “foo.js”,
 content: “I <3 MJS!” } } Performs
 XHR request XHR response
  48. .get() Store View Store View Action Dispatcher Store View Action


    Creator Dispatcher onInteraction on
 Change Store { type: “FILE_REQ_BEGIN”, payload: { fileName: “foo.js” } } { type: “FILE_REQ_SUCCESS”, payload: { fileName: “foo.js”,
 content: “I <3 MJS!” } } No Promises in actions! Performs
 XHR request XHR response
  49. Restrictions 㱺 Modular apps enforced naturally
 㱺 Avoid common error

    sources Practical Rules ③ Stores are updated only via Actions ④ Views refresh on Store’s changeEvent ⑤ Views query data via Store’s getter functions FLUX RestrictionS ① Information flows in one direction ② Only Single Action at any point in time
  50. React Container-Component <FileTreeControler> </FileTreeControler> <FileTreeEntry name=“foo” path=“…” isExpanded=true isFolder=true />

    FS-Store FT-Store Dispatcher Action https://medium.com/@learnreact/container- components-c0e67432e005 :onToggle
  51. Single Action Show Stopper Only Single Action at the time:

    • Prevent may common coding patterns
  52. Single Action Show Stopper Only Single Action at the time:

    • Prevent may common coding patterns • Solution not always obvious
  53. Single Action Show Stopper Only Single Action at the time:

    • Prevent may common coding patterns • Solution not always obvious BUT: Flux was always right in my experience! Take it as a sign that you try
 to build a part in your app
 that is not modular!
  54. Single Action Show Stopper Only Single Action at the time:

    • Prevent may common coding patterns • Solution not always obvious BUT: Flux was always right in my experience! Helpful question to ask:
 “If I add this, is it still easy to write contained tests?”
 “Create smaller actions and dispatch them sequential?” Take it as a sign that you try
 to build a part in your app
 that is not modular!
  55. Single Action Show Stopper View Action
 Creator A Cascading Updates!

    View Action
 Creator B :onExpand :onInitialRender
  56. Single Action Show Stopper View Action
 Creator A Cascading Updates!

    Fix View Action
 Creator B :onExpand :onInitialRender
  57. Single Action Show Stopper View Action
 Creator A Cascading Updates!

    Fix View Action
 Creator B View Action
 Creator A :onExpand :onInitialRender :onExpand
  58. Single Action Show Stopper View Action
 Creator A Cascading Updates!

    Fix View Action
 Creator B View Action
 Creator A Action
 Creator B :onExpand :onInitialRender :onExpand
  59. Flux Implementations • FB Flux: https://facebook.github.io/flux/ • Fluxxor: http://fluxxor.com/ •

    Reflux: https://github.com/spoike/refluxjs • Fluxible: http://fluxible.io/ • Flummox: https://github.com/acdlite/flummox Isomorphic: Work on server as well
  60. Redux https://github.com/gaearon/redux • Think about it as lambda calculus for

    app design • Goal: Keep it • simple • modular / separated
  61. Redux https://github.com/gaearon/redux • Think about it as lambda calculus for

    app design • Goal: Keep it • simple • modular / separated (e.g. stores are stateless!!!)
  62. Redux https://github.com/gaearon/redux • Think about it as lambda calculus for

    app design • Goal: Keep it • simple • modular / separated • functional (e.g. stores are stateless!!!)
  63. Redux https://github.com/gaearon/redux • Think about it as lambda calculus for

    app design • Goal: Keep it • simple • modular / separated • functional • Result: “WTF” 㱺 “MAGIC” 㱺 “TESTABLE!!!” (e.g. stores are stateless!!!)
  64. View Action
 Creator Dispatcher onInteraction on
 Change .get() Store Store

    (store, actions) -> (components) View Dependency
 Injection FTW
  65. View Action
 Creator Dispatcher onInteraction on
 Change .get() Store Store

    (state, action) -> (state’) Store (store, actions) -> (components) View Dependency
 Injection FTW
  66. View Action
 Creator Dispatcher onInteraction on
 Change .get() Store Store

    (state, action) -> (state’) Store (store, actions) -> (components) View Dependency
 Injection FTW Where is store state?
  67. View Action
 Creator Dispatcher onInteraction on
 Change .get() Store Store

    (state, action) -> (state’) Store (store, actions) -> (components) View Dependency
 Injection FTW → All in dispatcher! → Hot reloading Where is store state?
  68. View Action
 Creator Dispatcher onInteraction on
 Change .get() Store Store

    (state, action) -> (state’) Store (store, actions) -> (components) View () -> Action 
 () -> (dsptch -> Action)
 () -> ((dsptch, state) -> Action) ActionCreator Dependency
 Injection FTW → All in dispatcher! → Hot reloading Where is store state?
  69. The following examples are taken 
 from the Readme.md file

    at: 
 https://github.com/gaearon/redux
  70. Handling Derived Data • Idea: • Stores have normalised data

    • Use a special store to get derived data • Stores consuming actions should NOT work on derived data directly
  71. Flux + X Your App Vanilla JS React.JS Fluxxor Backbone

    } Flexible / adjustable concept Easy to extend existing code Angular.JS FB Flux Reflux Fluxible Flummox … …
  72. What Flux Feels To Me • App structure falls into

    place naturally • Bundle Data + Controller = Store feels good • Enforcing independent stores useful • Actions encode higher semantic level • Easier to think / reason about App • No interleaving actions / synchronous code • Easier to test Store Store
  73. Summary 1. Flux is not an implementation - it’s a

    philosophy • Data flows one direction • One action at the time 2. Your App: “Flux + X” • Combine with other library • Easy to restructure existing app 3. Flux gives useful guidance - you still can go off-road