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

Reimagining Redux

Reimagining Redux

Avatar for Ethan McCue

Ethan McCue

October 25, 2017
Tweet

Other Decks in Programming

Transcript

  1. Background • Redux is “a predictable state container for JavaScript

    apps.” • Its primary use case for building ‘functional’ web apps. • Efficient use relies on immutable data and pure functions.
  2. Background • Immutable.js is a JavaScript library for immutable data

    structures. • This means that all methods don’t alter an existing structure, but return a brand new structure. • This is made efficient by structural sharing (a.k.a. graph magic).
  3. How the system is supposed to work Action • Dispatch

    a message to the data store Update • Produce a new state using a pure function View • Update any Components that depend on the state
  4. Issues • A data store connects to components in a

    roundabout way Create Component Connect Component to store using magic “connect” function
  5. Issues • Over time, the codebase became littered with abuses

    of the redux system • Most recently, a module popped up in an application that lets the server directly send redux commands to all connected clients. • This means that the server had direct knowledge of how the frontend is structured, which is a general no-no. • Replacing redux with something that has a more targeted use and more specific documentation would go a long way to reducing these kinds of antipatterns.
  6. Issues • Code reuse across the various projects in production

    has been, unfortunately, very low • This is a general issue and needs to be tackled one brick at a time • Sharing code for a data store is a good a place as any to start
  7. The Goals • Write a functional data store to take

    the place of redux • Make it easy to integrate with existing Components and general enough to integrate with any future system • Make it clear what data can be taken from the store and what events will transform the store • Make the system as reusable as possible
  8. Prior Art • One of the first functional data stores

    that came out for the browser was ClojureScript’s re-frame.
  9. Prior Art • re-frame works in a fairly simple way.

    • Just as in redux, events trigger an update to the data. • After any change, a list of “subscriptions” is calculated. • If the value of a subscription changes: • Re-render any components that depend on that subscription. Events Update Store Subs. Render
  10. The Interface • The four basic pieces of functionality from

    re-frame are subscribe, dispatch, register event, and register subscription • I chose to define each of these as part of a generic interface that depends on the concept of a “notifiable”, which will be “told” when the subscription it depends on has changed
  11. Implementation: Subscribe • The subscribe method is called with a

    reference to the “notifiable” that is subscribing to the value. • That INotifiable is then added to a dictionary of subscribers associated with the name of the subscription.
  12. Implementation: Dispatch • The dispatch method is called with an

    event name and a variable amount of arguments to apply. • After each dispatch, the value for each subscription is recalculated, and any INotifiables that depend on subscription values that have changed are told that a change has occured
  13. Implementation: Register Subscription • Dead simple: The function is memoized

    and put into a dictionary with the key being the name of the subscription • It is safe to memoize the function because we are assuming that it is pure regardless • This has the nice benefit of making the calculation of new subscription values very fast if the value hasn’t changed
  14. Implementation: Register Dispatch • Exactly the same as for registering

    a subscription function, except it is put in a different dictionary
  15. Tying to Components • To make a version of this

    generic data store work with React components, all that was needed was to subclass and override subscribe. • The new subscribe wraps any React components passed to it in an INotifiable that causes a re-render whenever it is notified of a change.
  16. Tying to Components • To use data from the data

    store it is then sufficient to call subscribe directly from the render function. • Because subscriptions are stored in a dictionary, it is safe to call subscribe multiple times.
  17. Lessons Learned • Newer does not necessarily mean better, especially

    in the JavaScript world. • Be the change you want to see in the world