Repository: mozilla-services/react-jsonschema-form (js)

Issue:
File object becomes a basic js object
### Description
When we use the From component in a wrapper component and pass formData via props., the Form component transforms Props to State in `componentWillReceiveProps ` . Problem is when we use a custom widget with an input file, the `File` object is transformed to a basic object in [mergeObjects function](https://github.com/mozilla-services/react-jsonschema-form/blob/master/src/utils.js#L242) because the  `File` object is detected as an object.

I guess the solution is to exclude File from [isObject](https://github.com/mozilla-services/react-jsonschema-form/blob/master/src/utils.js#L232) function. 

Do you think it's the way to go? I don't see any exception than `File` object which could be bad detected.

### Steps to Reproduce

1. Open https://codesandbox.io/s/n4mlxwq3ml
2. Open the browser console
3. Choose a file
4. See in the console onChange event is triggered twice and the File object changes.

#### Expected behavior
The File object stays a File object

#### Actual behavior

The File object becomes a basic js object

### Version

1.3.0


Pull request:
Fix #1233 : Exclude File object from isObject detection
### Reasons for making this change
Fix https://github.com/mozilla-services/react-jsonschema-form/issues/1233



Patch:
diff --git a/src/utils.js b/src/utils.js
index 36376e436..ce13634b5 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -229,6 +229,9 @@ export function getUiOptions(uiSchema) {
 }
 
 export function isObject(thing) {
+  if (thing instanceof File) {
+    return false;
+  }
   return typeof thing === "object" && thing !== null && !Array.isArray(thing);
 }
 


Test patch:
diff --git a/test/setup-jsdom.js b/test/setup-jsdom.js
index 3cbf2cd12..d9f1115da 100644
--- a/test/setup-jsdom.js
+++ b/test/setup-jsdom.js
@@ -6,6 +6,7 @@ if (!global.hasOwnProperty("window")) {
   global.document = jsdom.jsdom("<!doctype html><html><body></body></html>");
   global.window = document.defaultView;
   global.navigator = global.window.navigator;
+  global.File = global.window.File;
 }
 
 // atob
diff --git a/test/utils_test.js b/test/utils_test.js
index bb61973f2..2f1ecc369 100644
--- a/test/utils_test.js
+++ b/test/utils_test.js
@@ -549,6 +549,17 @@ describe("utils", () => {
       expect(mergeObjects(obj1, obj2)).eql(expected);
     });
 
+    it("should recursively merge File objects", () => {
+      const file = new File(["test"], "test.txt");
+      const obj1 = {
+        a: {},
+      };
+      const obj2 = {
+        a: file,
+      };
+      expect(mergeObjects(obj1, obj2).a).instanceOf(File);
+    });
+
     describe("concatArrays option", () => {
       it("should not concat arrays by default", () => {
         const obj1 = { a: [1] };