Migrate Knockout to React

JavaScript pattern

Knockout.js is an older JavaScript framework that is still used by many developers. This migration helps with migrating your Knockout code to React.

HelloWorld View Model

BEFORE
var ViewModel = function (first, last) {
  this.firstName = ko.observable(first);
  this.lastName = ko.observable(last);

  this.fullName = ko.computed(function () {
    return this.firstName() + ' ' + this.lastName();
  }, this);
};
AFTER
import { useState } from 'react';

var ViewComponent = function (props) {
  const [firstName, setFirstName] = useState(props.firstName);
  const [lastName, setLastName] = useState(props.lastName);

  const name = useMemo(function () {
    return firstName + ' ' + lastName;
  });
};

Unhandled

These are cases we don't yet handle properly:

This is a simple sample taken from Wire.

JAVASCRIPT
ko.components.register('legal-hold-dot', {
  template: `
    <div class="legal-hold-dot"
         data-bind="click: onClick, css: {'legal-hold-dot--interactive': isInteractive, 'legal-hold-dot--large': large, 'legal-hold-dot--active': !isPending()}">
      <!-- ko if: isPending() -->
        <pending-icon></pending-icon>
      <!-- /ko -->
    </div>
    `,
  viewModel: function ({
    isPending = ko.observable(false),
    large = false,
    conversation,
    legalHoldModal,
  }: LegalHoldParams = {}): void {
    this.large = large;
    this.isPending = isPending;
    this.isInteractive = !!legalHoldModal;

    this.onClick = (_data: unknown, event: MouseEvent): void => {
      event.stopPropagation();
      if (this.isInteractive) {
        if (isPending()) {
          legalHoldModal.showRequestModal(true);
          return;
        }
        if (conversation) {
          legalHoldModal.showUsers(conversation);
          return;
        }
        legalHoldModal.showUsers();
      }
    };
  },
});

Prior Art

  • https://github.com/wireapp/wire-webapp/wiki/Knockout-to-React-Migration
    • https://github.com/wireapp/wire-webapp/pull/10329/files
    • https://github.com/wireapp/wire-webapp/pull/10387/files
  • https://github.com/lelandrichardson/knockout-react