isSavingPost() for widgets

If the goal is to display the block ID so that the user can get it easily, instead try using a block editor filter to add a panel in the sidebar:

From: https://developer.wordpress.org/block-editor/reference-guides/filters/block-filters/#editor-blockedit

const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;
 
const withInspectorControls = createHigherOrderComponent( ( BlockEdit ) => {
    return ( props ) => {
        return (
            <Fragment>
                <BlockEdit { ...props } />
                <InspectorControls>
                    <PanelBody>My custom control</PanelBody>
                </InspectorControls>
            </Fragment>
        );
    };
}, 'withInspectorControl' );
 
wp.hooks.addFilter(
    'editor.BlockEdit',
    'my-plugin/with-inspector-controls',
    withInspectorControls
);

Then inside the panel, use props to retrieve the blocks ID and display it, perhaps in an input with the disabled property. Specifically clientId.

It might look like this (untested):

const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;
 
const withWidgetIDPanel = createHigherOrderComponent( ( BlockEdit ) => {
    return ( props ) => {
        const widgetID = props.__internalWidgetId ? props.__internalWidgetId : 0;
        return (
            <Fragment>
                <BlockEdit { ...props } />
                <InspectorControls>
                    <PanelBody>
                        <input
                            class="components-text-control__input"
                            type="text"
                            disabled
                            value={ props.widgetID }
                        />
                    </PanelBody>
                </InspectorControls>
            </Fragment>
        );
    };
}, 'withWidgetIDPanel' );
 
wp.hooks.addFilter(
    'editor.BlockEdit',
    'tomjn/display-widget-id',
    withWidgetIDPanel
);

This will give you the widget ID if it’s available in the sidebar for every legacy widget if enqueued on the widgets page, and provides a useful debug panel for non-widget editors too. It also gives you a place to use react hooks and other WordPress APIs in the context of a specific block, without needing to figure out which widget belongs to which block ID.

Note that when the widget ID changes, React will re-render the component automatically, no subscription is necessary. Note that no local state is in use.

Frontend Block ID

If however you want the ID that gets used on the frontend, there’s an attribute named __internalWidgetId. When this changes React will re-render the edit component because its props have changed, so no subscription to the store is necessary.

Before the widget is saved, this __internalWidgetId attribute does not exist, and will be null if accessed, and when it comes into existence again the edit component will re-render because changed props are how React knows to re-render a DOM element.

Storing the widget ID in local state is not necessary and could lead to problems. Just pass the raw attribute down if it’s not null to any child components that need it or use the internal widget ID directly.

As a bonus, you can select on the core/edit-widgets store to grab the widget data directly.