Edit in JSFiddle

// inspired by https://github.com/odoe/esrijs4-vm-react
// I've added links to the relative sections in Odoe's code.
var dojoConfig = {
  async: true
};
require([
  "esri/Map",
  "esri/views/SceneView",
  "esri/views/MapView",
  "dojo/_base/declare",
  "dijit/_WidgetBase",
  "dijit/_TemplatedMixin",
  "dojo/Stateful",
  "dojo/_base/lang",
  "dojo/dom-style",
  "esri/widgets/BasemapToggle/BasemapToggleViewModel",
  "dojo/domReady!"
],
function(Map, SceneView, MapView, declare, _WidgetBase, _TemplatedMixin, Stateful, lang, domStyle, BasemapToggleVM) {
	var BToggle = declare([_WidgetBase, _TemplatedMixin, Stateful], {
  
  	// https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L75-L78
  	templateString: '<div><div class="basemap-item basemap-item-secondary" data-dojo-attach-event="click:toggle" data-dojo-attach-point="secondaryBasemapItem"></div><div class="basemap-item basemap-item-current" data-dojo-attach-point="currentBasemapItem"></div></div>',
    
    // https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L5-L9
    bgImage: function(target, url) {
    	domStyle.set(target, 'background-image', 'url(' + url + ')');
    },
    
    // https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L13-L18
    constructor: function() {
      this.inherited(arguments);
      this.vm = new BasemapToggleVM();
      this.secondaryThumbnailUrl = '';
    },
    
    // https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L29-L50
    postCreate: function() {
    	this.inherited(arguments);
      this.vm.view = this.view;
      this.vm.secondaryBasemap = this.secondaryBasemap;
 
      var info = this.vm.getBasemapInfo(this.secondaryBasemap || 'topo');
      this.updateThumbnails(info, this.vm.currentBasemap);
      this.vm.watch('secondaryBasemap', lang.hitch(this, 'updateThumbnails'));
    },
    
    // https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L52-L59
    updateThumbnails: function(secondary, current) {
      var secInfo = this.vm.getBasemapInfo(secondary);
      var curInfo = this.vm.getBasemapInfo(current);
    	this.bgImage(this.secondaryBasemapItem, secInfo.thumbnailUrl);
      this.bgImage(this.currentBasemapItem, curInfo.thumbnailUrl);
    },
    
    // https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L61-L63
    toggle: function(evt) {
    	this.vm.toggle();
    }
  });
  
  var map = new Map({
    basemap: "streets"
  });
  
  var viewOptions = {
    container: "viewDiv",
    map: map,
    center: [-101.17, 21.78],
    scale: 50000000
  };

  // 2D View:
  var view = new MapView(viewOptions);

	// Using our custom basemap (BToggle), defined above
  // Similar to https://github.com/odoe/esrijs4-vm-react/blob/master/src/main.jsx#L31
  var basemapToggle = new BToggle({
      view: view,
      secondaryBasemap: "dark-gray"
    }, "appDiv");
  basemapToggle.startup();
});