You are using a browser that is no longer supported. Please use the latest version of Google Chrome, Mozilla Firefox, Apple Safari, or Microsoft Edge. For more information please see the System Requirements.

Unsupported browser

You are using a browser that is not supported. JavaScript API works on the latest versions of Google Chrome, Mozilla Firefox, Apple Safari, or Microsoft Edge. Use one of these browsers and provide your feedback through GeoNet, the Esri Community.

  • {i18n.unsupportedBrowser.chrome}
  • Firefox
  • Safari
  • undefined
Loading...

Note: Support for 3D on mobile devices may vary, view the system requirements for more information.

This sample shows how to use React with ViewModels to create a custom widget experience. Specfically, 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: "https://unpkg.com/react@16/umd/",
      main: "react.production.min"
    },
    {
      name: "react-dom",
      location: "https://unpkg.com/react-dom@16/umd/",
      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() {
    this.props.view.when(this.onViewLoaded);
  }

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

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

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

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

  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>
        </div>
        <div className={minstate} onClick={this.zoomOut}>
          <div className="center">
            <i className="material-icons">remove</i>
          </div>
        </div>
      </div>
    );
  }
}

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);

Sample search results

TitleSample
Loading...