Repository: facebook/react
File: packages/react-client/src/ReactFlightReplyClient.js (JavaScript)

Code before:
        const data: FormData = formData;
        const refId = nextPartId++;
        // Copy all the form fields with a prefix for this reference.
        // These must come first in the form order because we assume that all the
        // fields are available before this is referenced.
        const prefix = formFieldPrefix + refId + '_';
        // $FlowFixMe[prop-missing]: FormData has forEach.
        value.forEach((originalValue: string | File, originalKey: string) => {
          data.append(prefix + originalKey, originalValue);
        });
        return serializeFormDataReference(refId);
      }
      if (!isArray(value)) {
        const iteratorFn = getIteratorFn(value);
        if (iteratorFn) {
          return Array.from((value: any));
        }
      }

      if (__DEV__) {
        if (value !== null && !isArray(value)) {
          // Verify that this is a simple plain object.
          if ((value: any).$$typeof === REACT_ELEMENT_TYPE) {
            console.error(
              'React Element cannot be passed to Server Functions from the Client.%s',
              describeObjectForErrorMessage(parent, key),
            );
          } else if ((value: any).$$typeof === REACT_LAZY_TYPE) {
            console.error(
              'React Lazy cannot be passed to Server Functions from the Client.%s',
              describeObjectForErrorMessage(parent, key),
            );
          } else if ((value: any).$$typeof === REACT_PROVIDER_TYPE) {
            console.error(
              'React Context Providers cannot be passed to Server Functions from the Client.%s',
              describeObjectForErrorMessage(parent, key),
            );
          } else if (objectName(value) !== 'Object') {
            console.error(
              'Only plain objects can be passed to Client Components from Server Components. ' +
                '%s objects are not supported.%s',
              objectName(value),
              describeObjectForErrorMessage(parent, key),
            );
          } else if (!isSimpleObject(value)) {
            console.error(
              'Only plain objects can be passed to Client Components from Server Components. ' +
                'Classes or other objects with methods are not supported.%s',
              describeObjectForErrorMessage(parent, key),
            );
          } else if (Object.getOwnPropertySymbols) {

Review comment (refactor):
~question: What's the purpose of the `Array.from` call here? I thought we already can stringify iterables so this seems redundant. Tests are passing without it.~ We `Array.from` it later anyway after we extracted the iterator so we might as well do it here since we know the value is iterable.

Code after:
            // that throws on the server instead.
            reject(reason);
          },
        );
        return serializePromiseID(promiseId);
      }
      // TODO: Should we the Object.prototype.toString.call() to test for cross-realm objects?
      if (value instanceof FormData) {
        if (formData === null) {
          // Upgrade to use FormData to allow us to use rich objects as its values.
          formData = new FormData();
        }
        const data: FormData = formData;
        const refId = nextPartId++;
        // Copy all the form fields with a prefix for this reference.
        // These must come first in the form order because we assume that all the
        // fields are available before this is referenced.
        const prefix = formFieldPrefix + refId + '_';
        // $FlowFixMe[prop-missing]: FormData has forEach.
        value.forEach((originalValue: string | File, originalKey: string) => {
          data.append(prefix + originalKey, originalValue);
        });
        return serializeFormDataReference(refId);
      }
      if (value instanceof Map) {
        const partJSON = JSON.stringify(Array.from(value), resolveToJSON);
        if (formData === null) {
          formData = new FormData();
        }
        const mapId = nextPartId++;
        formData.append(formFieldPrefix + mapId, partJSON);
        return serializeMapID(mapId);
      }
      if (value instanceof Set) {
        const partJSON = JSON.stringify(Array.from(value), resolveToJSON);
        if (formData === null) {
          formData = new FormData();
        }
        const setId = nextPartId++;
        formData.append(formFieldPrefix + setId, partJSON);
        return serializeSetID(setId);
      }
      if (!isArray(value)) {
        const iteratorFn = getIteratorFn(value);
        if (iteratorFn) {
          return Array.from((value: any));
        }
      }

      if (__DEV__) {
        if (value !== null && !isArray(value)) {