BCP UI Architecture

Current State

jQuery

  • Popular utility library for DOM interaction
  • Abstraction over DOM, XHR, and other browser APIs
  • Unstructured, spaghetti code

jQuery


    <div class="bcp-acordion" data-component="accordion">
        <button data-role="accordion-trigger" type="button">Toggle</button>
        <p>Content goes here.</p>
    </div>

    <script>
        var Accordion = (function () {

            this.toggle = function() {
                $('[data-component="accordion"]').toggleClass('is-expanded');
            };
            
            $(document).on('click', '[data-component="accordion"]
                [data-role="accordion-trigger"]', toggle);
        }());
    </script>

Knockout JS

  • Uses a template engine
  • Declarative two-way data binding
  • Supports computed properties

KnockoutJS


    <div class="bcp-acordion" data-component="accordion"                 
        data-bind="css: {'is-expanded': isExpanded}">
        <button data-bind="click: toggle" type="button">Toggle</button>
        <p>Content goes here.</p>
    </div>

    <script>
        var Accordion = function() {
            this.isExpanded = ko.observable(false);
        };

        ko.applyBindings(Accordion, 
            document.querySelector('[data-component="accordion"]');
    </script>

Problems

  • Code duplication
  • Business logic, application data, and UI code all mixed
  • Custom code / reinventing the wheel
  • Hard to maintain and scale
  • Difficult to debug and test

Future State

React

  • Component-based architecture
  • Uses virtual DOM
  • UI is a representation of your data

React


    <div data-component="accordion"></div>

    <script>
      class Accordion extends React.Component {
        state = { expanded: false }
        render() {
          return (
            <div className={classNames('bcp-accordion',
              'is-expanded': this.state.expanded)}>
               <button onClick={this.setState({ expanded: !expanded })}>
                 Toggle
               </button>
               <p>Content goes here.<p>
             </div>
          );
        }
      }

      ReactDOM.render(Accordion, 
        document.querySelector('[data-component="accordion"]');
    </script>

Redux

  • Unidirectional data flow
  • Single source of truth
  • State is read-only
  • Changes are made with pure functions

Redux


    const toggleAccordion = () => ({
        type: 'bcp/accordion/TOGGLE'
    });

    const initialState = {
        expanded: false
    };

    const reducer = (state = initialState, action = {}) => {
        
        switch (action.type) {
            case 'bcp/accordion/TOGGLE':
                return {
                    ...state,
                    expanded: !expanded
                };
            default:
                return state;
        }
    };

Solutions

  • Module system
  • Reusable components
  • Separation of UI and business logic
  • Utilizing open source packages
  • Easy to debug and test

Additional Benefits

  • Truly reusable components
  • Use of modern JavaScript syntax and features
  • Cleaner, more concise code
  • Build process enforces linting and testing rules
  • Bundler allows code splitting and async loading

Questions about React

Redux Architecture

Redux Architecture

Questions about Redux

Thank you! 🤗

Made with Slides.com