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


Apply with the Grit CLI
grit apply knockout_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

JavaScript pattern

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

JavaScript pattern
  • 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