wp.data is a store, and the editor’s state is queryable

The editor keeps its state in a Redux-like store, and everything on screen is derived from it — which means a plugin can read the current post, the selected block or the save status without touching the DOM.

const { select, subscribe, dispatch } = wp.data;

select('core/editor').getEditedPostAttribute('title');
select('core/block-editor').getSelectedBlock();
select('core/editor').isSavingPost();

// and a subscription that fires on every state change
const unsubscribe = subscribe(() => {
  if (select('core/editor').isCurrentPostPublished()) {
    // ...
  }
});

The subscription fires on every change including keystrokes, so the callback has to be cheap and has to compare against a previous value it keeps itself — otherwise a publish handler runs a hundred times. Store names moved during 5.x, with block-related selectors migrating from core/editor to core/block-editor, so examples from 2018 silently return undefined. Checking which store a selector lives in is the first debugging step.