Using widgets with React

Explore in the sandboxView live

This sample shows how to use React with ViewModels to create a custom widget experience. Specifically, it demonstrates how to use the ZoomViewModel to create a custom Zoom button.

1. Set up React as AMD modules

First, you need to add React and ReactDOM as AMD modules in your dojoConfig.

window.dojoConfig = {
  async: true,
  packages: [
      name: "react",
      location: "",
      main: "react.production.min"
      name: "react-dom",
      location: "",
      main: "react-dom.production.min"

Now you can start using them as normal AMD modules.

2. Create a simple map and view

Create a simple map and add it to either a MapView or a SceneView. If you are unfamiliar with views or how to create a basic map, see the following resources:

var map = new Map({
  basemap: "topo-vector"

var view = new MapView({
  container: "viewDiv",
  map: map,
  center: [-100.33, 25.69],
  zoom: 10,
  ui: {
    components: ["attribution"] // empty the UI, except for attribution

3. Create a React component

Create a React component with an initial state and predefined properties. For more information on this, see the React documentation. Next, bind the actions of the React component to the methods of the ZoomViewModel. It is also possible to bind the React component's style with the View's properties to determine the current min/max zoom level.

class Zoom extends React.Component {
  state = {
    vm: new ZoomViewModel(),
    maxZoomed: false,
    minZoomed: false

  componentDidMount() {

  onViewLoaded = (view) => {
    this.state.vm.view = view;
    watchUtils.init(view, "zoom", this.onZoomChange);

  onZoomChange = (value) => {
      maxZoomed: value === view.constraints.maxZoom,
      minZoomed: value === view.constraints.minZoom

  zoomIn = () => {
    if (!this.state.maxZoomed) {

  zoomOut = () => {
    if (!this.state.minZoomed) {

  render() {
    const maxstate = this.state.maxZoomed ? "button circle raised disable" : "button circle raised";
    const minstate = this.state.minZoomed ? "button circle raised disable" : "button circle raised";
    return (
      <div className="zoom-btns">
        <div className={maxstate} onClick={this.zoomIn}>
          <div className="center">
            <i className="material-icons">add</i>
        <div className={minstate} onClick={this.zoomOut}>
          <div className="center">
            <i className="material-icons">remove</i>

4. Render the React Component

Next, create a DOM element for the React component and add it to the UI layout.Once finished, render the React component.

const node = document.createElement("div");
view.ui.add(node, "bottom-left");
ReactDOM.render(<Zoom view={view} />, node);