ArcGIS for Developers

Widget communication

A widget in Experience Builder is a function unit: one widget completes one focused function only. However, we need multiple widgets to work together to complete one task in many cases, so we need some ways to support how widgets talk to each other at the framework level. We support the following ways:

  • Message action. This mechanism is a configurable solution for widget to widget communication. See Message action for details.
  • Share state. This mechanism is a programming solution for widget to widget communication. There are two ways to share state between widgets: use widget state and provide your own Redux store/action/reducer.

Use widget state to share state between widgets

Widget as a React component can have an internal state, but other widgets cannot access this state. Jimu uses Redux as its state manager; it saves a lot of info in the Redux store. One piece of the info is called widgetsState; you can find the type definition at jimu-core/lib/types/state. The info stored in widgetsState is accessible by all of the other widgets. To save some info in the widgetsState, please refer to this code snippet:

          
import {appActions} from 'jimu-core';

/*
* Call this when you need to save state.
*
* widgetId: your widget id
* propKey: can be a string with this format "a.b.c"
* value: the info you want to store
*/
this.props.dispatch(appActions.widgetStatePropChange(widgetId, propKey, value))

For example, if you call this.props.dispatch(appActions.widgetStatePropChange("w1", "a.b1", "value1")) and this.props.dispatch(appActions.widgetStatePropChange("w1", "a.b2", "value2")), you'll get this store state in the Redux store:

        
widgetsState: {
    w1: {
        a: {
            b1: 'value1',
            b2: 'value2'
        }
    }
}

To access the info stored by w1 in widget 2, you can select the value from store by using mapExtraStateProps or using useSelect hooks.

However, you can store plain JavaScript objects in widgetsState only. To store some complex JavaScript objects, you can use this.props.dispatch(appActions.widgetMutableStatePropChange(widgetId, propKey, value)) to store value, and use MutableStoreManager.getInstance().getStateValue() to access it.

Provide your own redux store/action/reducer to share state between widgets

This provides a more flexible way to customize your state management. You can find this is almost the same as what you do in the normal Redux way. As we know, Redux has only one store and one root reducer, which is used by jimu. To let the widget developer use the normal Redux way to manage state, jimu defines a ReduxStore extension point; widgets that need to use Redux can provide an extension for this extension point.

  • Create an extension class to implement the ReduxStoreExtension interface; let's call it my-store.ts.
                   
import {extensionSpec} from 'jimu-core';

export default class MyReduxStoreExtension implements extensionSpec.ReduxStoreExtension{
    getActions(){
        // return your redux actions.
    }

    getInitLocalState(){
        // return your redux init local state.
    }

    getReducer(){
        // return your redux reducer.
    }

    getStoreKey(){
        // return your redux local key.
    }
}
  • Declare the extension in widget manifest.json
       
"extensions": [
    {
      "name": "My Store",
      "point": "REDUX_STORE",
      "uri": "my-store"
    }
  ]