diff --git a/core/misc/states.js b/core/misc/states.js
index 487a412190830fec676b1f9fe39f44b4a6cf0432..39cd7b41bb3a5fb119eed3c5fe93e6dcb6c581ac 100644
--- a/core/misc/states.js
+++ b/core/misc/states.js
@@ -722,7 +722,7 @@
 
   $document.on('state:checked', (e) => {
     if (e.trigger) {
-      $(e.target).prop('checked', e.value);
+      $(e.target).prop('checked', e.value).trigger('change');
     }
   });
 
diff --git a/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php b/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php
index 4d589d349d35ca99f9bb08a77db6642e5eb79614..4f8095739ff2c0e04bdad0b94f6c0ae73be01596 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php
@@ -31,6 +31,52 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#type' => 'textfield',
       '#title' => 'Textfield trigger',
     ];
+    $form['radios_opposite1'] = [
+      '#type' => 'radios',
+      '#title' => 'Radios opposite 1',
+      '#options' => [
+        0 => 'zero',
+        1 => 'one',
+      ],
+      '#default_value' => 0,
+      0 => [
+        '#states' => [
+          'checked' => [
+            ':input[name="radios_opposite2"]' => ['value' => 1],
+          ],
+        ],
+      ],
+      1 => [
+        '#states' => [
+          'checked' => [
+            ':input[name="radios_opposite2"]' => ['value' => 0],
+          ],
+        ],
+      ],
+    ];
+    $form['radios_opposite2'] = [
+      '#type' => 'radios',
+      '#title' => 'Radios opposite 2',
+      '#options' => [
+        0 => 'zero',
+        1 => 'one',
+      ],
+      '#default_value' => 1,
+      0 => [
+        '#states' => [
+          'checked' => [
+            ':input[name="radios_opposite1"]' => ['value' => 1],
+          ],
+        ],
+      ],
+      1 => [
+        '#states' => [
+          'checked' => [
+            ':input[name="radios_opposite1"]' => ['value' => 0],
+          ],
+        ],
+      ],
+    ];
     $form['radios_trigger'] = [
       '#type' => 'radios',
       '#title' => 'Radios trigger',
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php
index 259a7e146f0615c217bbf743f1d5485353548070..80790d48f33bdfee8c8ab0d5b05acf09f2c696cf 100644
--- a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php
+++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php
@@ -63,6 +63,7 @@ public function testJavascriptStates() {
     $this->doRadiosTriggerTests();
     $this->doSelectTriggerTests();
     $this->doMultipleTriggerTests();
+    $this->doNestedTriggerTests();
   }
 
   /**
@@ -322,4 +323,30 @@ protected function doMultipleTriggerTests() {
     $this->assertTrue($item_visible_value2_and_textfield->isVisible());
   }
 
+  /**
+   * Tests states of radios element triggered by other radios element.
+   */
+  protected function doNestedTriggerTests() {
+    $this->drupalGet('form-test/javascript-states-form');
+    $page = $this->getSession()->getPage();
+
+    // Find trigger and target elements.
+    $radios_opposite1 = $page->findField('radios_opposite1');
+    $this->assertNotEmpty($radios_opposite1);
+    $radios_opposite2 = $page->findField('radios_opposite2');
+    $this->assertNotEmpty($radios_opposite2);
+
+    // Verify initial state.
+    $this->assertEquals('0', $radios_opposite1->getValue());
+    $this->assertEquals('1', $radios_opposite2->getValue());
+
+    // Set $radios_opposite2 value to 0, $radios_opposite1 value should be 1.
+    $radios_opposite2->setValue('0');
+    $this->assertEquals('1', $radios_opposite1->getValue());
+
+    // Set $radios_opposite1 value to 1, $radios_opposite2 value should be 0.
+    $radios_opposite1->setValue('0');
+    $this->assertEquals('1', $radios_opposite2->getValue());
+  }
+
 }