diff --git a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
index 79b9292..430dcef 100644
--- a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
+++ b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
@@ -120,6 +120,13 @@
   protected $renderer;
 
   /**
+   * The 'system' channel logger service.
+   *
+   * @var \Psr\Log\LoggerInterface
+   */
+  protected $logger;
+
+  /**
    * {@inheritdoc}
    */
   public function __construct(array $values, $entity_type) {
@@ -132,6 +139,7 @@ public function __construct(array $values, $entity_type) {
     }
 
     $this->renderer = \Drupal::service('renderer');
+    $this->logger = \Drupal::logger('system');
 
     // A plugin manager and a context type needs to be set by extending classes.
     if (!isset($this->pluginManager)) {
@@ -428,19 +436,70 @@ public function onDependencyRemoval(array $dependencies) {
       }
     }
     foreach ($this->getComponents() as $name => $component) {
-      if (isset($component['type']) && $definition = $this->pluginManager->getDefinition($component['type'], FALSE)) {
-        if (in_array($definition['provider'], $dependencies['module'])) {
+      if ($renderer = $this->getRenderer($name)) {
+        if (in_array($renderer->getPluginDefinition()['provider'], $dependencies['module'])) {
           // Revert to the defaults if the plugin that supplies the widget or
           // formatter depends on a module that is being uninstalled.
           $this->setComponent($name);
           $changed = TRUE;
         }
+
+        // Give this component the opportunity to react on dependency removal.
+        if ($component_changed = $renderer->onDependencyRemoval($dependencies)) {
+          // Update component settings to reflect changes.
+          $component['settings'] = $renderer->getSettings();
+          $this->setComponent($name, $component);
+          $changed = TRUE;
+        }
+        // If there are unresolved deleted dependencies left, disable this
+        // component to avoid the removal of the entire display entity.
+        if ($this->checkUnresolvedDependencies($renderer->calculateDependencies(), $dependencies)) {
+          $this->removeComponent($name);
+          $arguments = [
+            '@display' => $this->getEntityType()->getLabel(),
+            '@id' => $this->id(),
+            '@name' => $name,
+          ];
+          $this->logger->warning("@display '@id': Component '@name' was disabled because its settings depend on removed dependencies.", $arguments);
+          $changed = TRUE;
+        }
       }
     }
     return $changed;
   }
 
   /**
+   * Checks if the plugin has unresolved dependencies against the display entity
+   * removed dependencies.
+   *
+   * Note:
+   * - The two arguments have not the same structure.
+   * - $removed_dependencies has already sane defaults. All the types of events
+   *   are filled in, even with empty arrays.
+   *
+   * @param array[] $plugin_dependencies
+   *   A list of dependencies having the same structure as the return value of
+   *   ConfigEntityInterface::calculateDependencies().
+   * @param array[] $removed_dependencies
+   *   A list of dependencies having the same structure as the input argument of
+   *   ConfigEntityInterface::onDependencyRemoval().
+   *
+   * @return bool
+   *   TRUE if there are unresolved dependencies in $plugin_dependencies.
+   *
+   * @see \Drupal\Core\Config\Entity\ConfigEntityInterface::calculateDependencies()
+   * @see \Drupal\Core\Config\Entity\ConfigEntityInterface::onDependencyRemoval()
+   */
+  protected function checkUnresolvedDependencies(array $plugin_dependencies, array $removed_dependencies) {
+    foreach ($plugin_dependencies as $type => $dependencies) {
+      if (array_intersect($dependencies, array_keys($removed_dependencies[$type]))) {
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function __sleep() {
diff --git a/core/lib/Drupal/Core/Field/PluginSettingsBase.php b/core/lib/Drupal/Core/Field/PluginSettingsBase.php
index 1baf31d..8e12df3 100644
--- a/core/lib/Drupal/Core/Field/PluginSettingsBase.php
+++ b/core/lib/Drupal/Core/Field/PluginSettingsBase.php
@@ -122,4 +122,11 @@ public function calculateDependencies() {
     return array();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function onDependencyRemoval(array $dependencies) {
+    return FALSE;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/PluginSettingsInterface.php b/core/lib/Drupal/Core/Field/PluginSettingsInterface.php
index 969061f..cc30eed 100644
--- a/core/lib/Drupal/Core/Field/PluginSettingsInterface.php
+++ b/core/lib/Drupal/Core/Field/PluginSettingsInterface.php
@@ -95,4 +95,29 @@ public function getThirdPartySetting($module, $key, $default = NULL);
    */
   public function setThirdPartySetting($module, $key, $value);
 
+  /**
+   * Runs update actions when this plugin is asked to react on removal of its
+   * dependencies.
+   *
+   * This method allows plugins to keep their configuration up-to-date when a
+   * dependency calculated with ::calculateDependencies() is removed. For
+   * example, an entity view display contains a formatter having a setting
+   * pointing to an arbitrary config entity. When that config entity is deleted,
+   * this method is called by the view display to react on the dependency
+   * removal by updating its configuration.
+   *
+   * This method must return TRUE if the removal event updated the plugin
+   * configuration or FALSE otherwise.
+   *
+   * @param array $dependencies
+   *   An array of dependencies that will be deleted keyed by dependency type.
+   *   Dependency types are 'config', 'content', 'module' and 'theme'.
+   *
+   * @return bool
+   *   TRUE if the plugin configuration has changed, FALSE if not.
+   *
+   * @see \Drupal\Core\Entity\EntityDisplayBase
+   */
+  public function onDependencyRemoval(array $dependencies);
+
 }
diff --git a/core/modules/field/tests/modules/field_test/config/schema/field_test.schema.yml b/core/modules/field/tests/modules/field_test/config/schema/field_test.schema.yml
index 8e06db1..04dc5fe 100644
--- a/core/modules/field/tests/modules/field_test/config/schema/field_test.schema.yml
+++ b/core/modules/field/tests/modules/field_test/config/schema/field_test.schema.yml
@@ -40,6 +40,12 @@ field.widget.settings.test_field_widget:
     test_widget_setting:
       type: string
       label: 'Test setting'
+    role:
+      type: string
+      label: 'A referenced role'
+    role2:
+      type: string
+      label: 'A 2nd referenced role'
 
 field.widget.settings.test_field_widget_multiple:
   type: mapping
diff --git a/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldWidget/TestFieldWidget.php b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldWidget/TestFieldWidget.php
index b90008a..a68e235 100644
--- a/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldWidget/TestFieldWidget.php
+++ b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldWidget/TestFieldWidget.php
@@ -34,6 +34,8 @@ class TestFieldWidget extends WidgetBase {
   public static function defaultSettings() {
     return array(
       'test_widget_setting' => 'dummy test string',
+      'role' => 'anonymous',
+      'role2' => 'anonymous',
     ) + parent::defaultSettings();
   }
 
@@ -78,4 +80,42 @@ public function errorElement(array $element, ConstraintViolationInterface $viola
     return $element['value'];
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function calculateDependencies() {
+    $dependencies = parent::calculateDependencies();
+
+    foreach (['role', 'role2'] as $setting) {
+      if (!empty($role_id = $this->getSetting($setting))) {
+        // Create a dependency on the role config entity referenced in settings.
+        $dependencies['config'][] = "user.role.$role_id";
+      }
+    }
+
+    return $dependencies;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function onDependencyRemoval(array $dependencies) {
+    $changed = parent::onDependencyRemoval($dependencies);
+
+    // Only the setting 'role' is resolved here. When the dependency related to
+    // this setting is removed, is expected that the widget component will be
+    // update accordingly in the display entity. The 'role2' setting is
+    // deliberately left out from being updated. When the dependency
+    // corresponding to this setting is removed, is expected that the widget
+    // component will be disabled in the display entity.
+    if (!empty($role_id = $this->getSetting('role'))) {
+      if (!empty($dependencies['config']["user.role.$role_id"])) {
+        $this->setSetting('role', 'anonymous');
+        $changed = TRUE;
+      }
+    }
+
+    return $changed;
+  }
+
 }
diff --git a/core/modules/field_ui/src/Tests/EntityDisplayTest.php b/core/modules/field_ui/src/Tests/EntityDisplayTest.php
index 82dc8ab..446208a 100644
--- a/core/modules/field_ui/src/Tests/EntityDisplayTest.php
+++ b/core/modules/field_ui/src/Tests/EntityDisplayTest.php
@@ -7,12 +7,17 @@
 
 namespace Drupal\field_ui\Tests;
 
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Database\Database;
+use Drupal\Core\Entity\Display\EntityDisplayInterface;
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\Core\Entity\Entity\EntityViewMode;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\node\Entity\NodeType;
 use Drupal\simpletest\KernelTestBase;
+use Drupal\user\Entity\Role;
 
 /**
  * Tests the entity display configuration entities.
@@ -435,4 +440,118 @@ public function testOnDependencyRemoval() {
     $display = entity_get_display('entity_test', 'entity_test', 'default');
     $this->assertFalse($display->getComponent($field_name));
   }
+
+  /**
+   * Tests components dependencies additions.
+   */
+  public function testComponentDependencies() {
+    $this->enableModules(['dblog']);
+    $this->installSchema('dblog', ['watchdog']);
+    $this->installEntitySchema('user');
+    /** @var \Drupal\user\RoleInterface[] $roles */
+    $roles = [];
+    // Create two arbitrary user roles.
+    for ($i = 0; $i < 2; $i++) {
+      $roles[$i] = Role::create([
+        'id' => Unicode::strtolower($this->randomMachineName()),
+        'label' => $this->randomString(),
+      ]);
+      $roles[$i]->save();
+    }
+
+    // Create a field of type 'test_field' attached to 'entity_test'.
+    $field_name = Unicode::strtolower($this->randomMachineName());
+    FieldStorageConfig::create([
+      'field_name' => $field_name,
+      'entity_type' => 'entity_test',
+      'type' => 'test_field',
+    ])->save();
+    FieldConfig::create([
+      'field_name' => $field_name,
+      'entity_type' => 'entity_test',
+      'bundle' => 'entity_test',
+    ])->save();
+
+    // Create a new form display without components.
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = EntityFormDisplay::create([
+      'targetEntityType' => 'entity_test',
+      'bundle' => 'entity_test',
+      'mode' => 'default',
+    ]);
+    $form_display->save();
+
+    $dependencies = ['user.role.' . $roles[0]->id(), 'user.role.' . $roles[1]->id()];
+
+    // The config object should not depend on none of the two $roles.
+    $this->assertFalse($this->isConfigDependency($dependencies[0], $form_display));
+    $this->assertFalse($this->isConfigDependency($dependencies[1], $form_display));
+
+    // Add a widget of type 'test_field_widget'.
+    $component = [
+      'type' => 'test_field_widget',
+      'settings' => [
+        'test_widget_setting' => $this->randomString(),
+        'role' => $roles[0]->id(),
+        'role2' => $roles[1]->id(),
+      ],
+    ];
+    $form_display->setComponent($field_name, $component);
+    $form_display->save();
+
+    // Now, the form display should depend on both user roles $roles.
+    $this->assertTrue($this->isConfigDependency($dependencies[0], $form_display));
+    $this->assertTrue($this->isConfigDependency($dependencies[1], $form_display));
+
+    // Delete the first user role entity.
+    $roles[0]->delete();
+
+    // Reload the form display.
+    $form_display = EntityFormDisplay::load($form_display->id());
+    // The form display should not depend on $role[0] anymore.
+    $this->assertFalse($this->isConfigDependency($dependencies[0], $form_display));
+    // The form display should depend on 'anonymous' user role.
+    $this->assertTrue($this->isConfigDependency('user.role.anonymous', $form_display));
+
+    // Delete the 2nd user role entity.
+    $roles[1]->delete();
+
+    // Reload the form display.
+    $form_display = EntityFormDisplay::load($form_display->id());
+    // The display exists.
+    $this->assertFalse(empty($form_display));
+    // The component has been disabled.
+    $this->assertNull($form_display->getComponent($field_name));
+    $this->assertTrue($form_display->get('hidden')[$field_name]);
+    // The correct warning message has been logged.
+    $arguments = ['@display' => t('Entity form display'), '@id' => $form_display->id(), '@name' => $field_name];
+    $logged = (bool) Database::getConnection()->select('watchdog', 'w')
+      ->fields('w', ['wid'])
+      ->condition('type', 'system')
+      ->condition('message', "@display '@id': Component '@name' was disabled because its settings depend on removed dependencies.")
+      ->condition('variables', serialize($arguments))
+      ->execute()
+      ->fetchField();
+    $this->assertTrue($logged);
+  }
+
+  /**
+   * Returns TRUE if $key is a config dependency of $entity_display.
+   *
+   * @param string $key
+   *   The string to be checked.
+   * @param \Drupal\Core\Entity\Display\EntityDisplayInterface $entity_display
+   *   The entity display object to get dependencies from.
+   *
+   * @return bool
+   *   If the supplied $key is a config dependency of the $entity_display.
+   *
+   * @see testComponentDependencies()
+   */
+  protected function isConfigDependency($key, EntityDisplayInterface $entity_display) {
+    $dependencies = $entity_display->getDependencies();
+    $config_dependencies = !empty($dependencies['config']) ? $dependencies['config'] : [];
+    return in_array($key, $config_dependencies);
+  }
+
 }
