diff --git a/core/modules/file/file.js b/core/modules/file/file.js
index 8ed377e..2b21621 100644
--- a/core/modules/file/file.js
+++ b/core/modules/file/file.js
@@ -36,6 +36,10 @@
         elements = settings.file.elements;
         Object.keys(elements).forEach(initFileValidation);
       }
+
+      // Trigger visible state to allow States to react to the loading of
+      // this element.
+      $(document).trigger('state:visible');
     },
     detach: function (context, settings, trigger) {
       var $context = $(context);
diff --git a/core/modules/file/src/Element/ManagedFile.php b/core/modules/file/src/Element/ManagedFile.php
index f465b18..6953393 100644
--- a/core/modules/file/src/Element/ManagedFile.php
+++ b/core/modules/file/src/Element/ManagedFile.php
@@ -13,6 +13,7 @@
 use Drupal\Core\Url;
 use Drupal\file\Entity\File;
 use Symfony\Component\HttpFoundation\Request;
+use Drupal\Core\Template\Attribute;
 
 /**
  * Provides an AJAX/progress aware widget for uploading and saving a file.
@@ -352,8 +353,17 @@ public static function processManagedFile(&$element, FormStateInterface $form_st
     // with it.
     $element['#id'] = &$element['upload']['#id'];
 
+    // Add states to ajax wrapper so states.js can potentially attach this
+    // element as a Dependent.
+    $attributes = '';
+    if (isset($element['#states']) && !empty($element['#states'])) {
+      $attributes = new Attribute([
+        'data-drupal-states' => json_encode($element['#states']),
+      ]);
+    }
+
     // Prefix and suffix used for Ajax replacement.
-    $element['#prefix'] = '<div id="' . $ajax_wrapper_id . '">';
+    $element['#prefix'] = '<div id="' . $ajax_wrapper_id . '"' . $attributes . '>';
     $element['#suffix'] = '</div>';
 
     return $element;
diff --git a/core/modules/file/tests/modules/file_test_states/file_test_states.info.yml b/core/modules/file/tests/modules/file_test_states/file_test_states.info.yml
new file mode 100644
index 0000000..0a3189b
--- /dev/null
+++ b/core/modules/file/tests/modules/file_test_states/file_test_states.info.yml
@@ -0,0 +1,8 @@
+name: 'File test states'
+type: module
+description: 'Provides a simple form with file fields using states.'
+package: Testing
+version: VERSION
+core: 8.x
+dependencies:
+  - file
diff --git a/core/modules/file/tests/modules/file_test_states/file_test_states.routing.yml b/core/modules/file/tests/modules/file_test_states/file_test_states.routing.yml
new file mode 100644
index 0000000..3e1bb3a
--- /dev/null
+++ b/core/modules/file/tests/modules/file_test_states/file_test_states.routing.yml
@@ -0,0 +1,7 @@
+example.form:
+  path: '/file-test-states-form'
+  defaults:
+    _title: 'File test states form'
+    _form: '\Drupal\file_test_states\Form\FileTestStatesForm'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/file/tests/modules/file_test_states/src/Form/FileTestStatesForm.php b/core/modules/file/tests/modules/file_test_states/src/Form/FileTestStatesForm.php
new file mode 100644
index 0000000..4cb3cbf
--- /dev/null
+++ b/core/modules/file/tests/modules/file_test_states/src/Form/FileTestStatesForm.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\file_test_states\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * A simple form with a file and manage_file to test states.
+ */
+class FileTestStatesForm extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'file_test_states_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $form['toggle'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Toggle fields'),
+    ];
+    $form['managed_file_initially_visible'] = [
+      '#type' => 'managed_file',
+      '#title' => t('Managed File Initially Visible'),
+      '#states' => [
+        'visible'  => [':input[name="toggle"]' => ['checked' => FALSE]],
+      ],
+    ];
+    $form['managed_file_initially_hidden'] = [
+      '#type' => 'managed_file',
+      '#title' => t('Managed File Initially Hidden'),
+      '#states' => [
+        'visible'  => [':input[name="toggle"]' => ['checked' => TRUE]],
+      ],
+    ];
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, FormStateInterface $form_state) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {}
+
+}
diff --git a/core/modules/file/tests/src/FunctionalJavascript/FileManagedStateTest.php b/core/modules/file/tests/src/FunctionalJavascript/FileManagedStateTest.php
new file mode 100644
index 0000000..828a253
--- /dev/null
+++ b/core/modules/file/tests/src/FunctionalJavascript/FileManagedStateTest.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Drupal\Tests\file\FunctionalJavascript;
+
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+
+/**
+ * Tests access to managed files.
+ *
+ * @group file
+ */
+class FileManagedStateTest extends JavascriptTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['file_test_states', 'file'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+  }
+
+  /**
+   * Tests if public file is always accessible.
+   */
+  public function testFileStateVisible() {
+    $this->drupalLogin($this->drupalCreateUser());
+    $this->drupalGet('file-test-states-form');
+
+    // Wait until the page has fully loaded including the ajax load of the
+    // managed files.
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $page = $this->getSession()->getPage();
+
+    // Now get the fields from the page.
+    $field_initially_visible = $page->findField('files[managed_file_initially_visible]');
+    $field_initially_hidden = $page->findField('files[managed_file_initially_hidden]');
+
+    // Check that the initially visible managed file is visible.
+    $this->assertTrue($field_initially_visible->isVisible());
+
+    // Check that the initially hidden managed file is hidden.
+    $this->assertFalse($field_initially_hidden->isVisible());
+
+    // Toggle the fields.
+    $page->findField('toggle')->click();
+
+    // Check that the initially visible managed file is now hidden.
+    $this->assertFalse($field_initially_visible->isVisible());
+
+    // Check that the initially hidden managed file is now visible.
+    $this->assertTrue($field_initially_hidden->isVisible());
+  }
+
+}
