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

Code before:
  reference: T,
  id: ServerReferenceId,
  encodeFormAction?: EncodeFormActionCallback,
): ServerReference<T> {
  const bound =
    isServerReference(reference) && reference.$$bound
      ? Promise.resolve(reference.$$bound)
      : null;

  registerBoundServerReference(reference, id, bound, encodeFormAction);
  return reference;
}

// $FlowFixMe[method-unbinding]
const FunctionBind = Function.prototype.bind;
// $FlowFixMe[method-unbinding]
const ArraySlice = Array.prototype.slice;

function defineBind<T: Function>(reference: T) {
  // TODO: Instead of checking if it's a server reference, we could also use
  // `reference.hasOwnProperty('bind')`.
  const originalBind = isServerReference(reference)
    ? reference.bind
    : FunctionBind;

  function bind(): Function {
    // $FlowFixMe[prop-missing]
    const newFn = originalBind.apply(reference, arguments);
    const metaData = knownServerReferences.get(reference);

    if (metaData) {
      if (__DEV__) {
        const thisBind = arguments[0];
        if (thisBind != null) {
          // This doesn't warn in browser environments since it's not
          // instrumented outside usedWithSSR. This makes this an SSR only
          // warning which we don't generally do.
          // TODO: Consider a DEV only instrumentation in the browser.
          console.error(
            'Cannot bind "this" of a Server Action. Pass null or undefined as the first argument to .bind().',
          );
        }
      }
      const args = ArraySlice.call(arguments, 1);
      let boundPromise = null;
      if (metaData.bound !== null) {
        boundPromise = Promise.resolve((metaData.bound: any)).then(boundArgs =>
          boundArgs.concat(args),
        );
      } else {
        boundPromise = Promise.resolve(args);

Review comment (suggestion):
This shouldn't use a closure. You should be able to have `referenceA.bind === referenceB.bind` and eventually this should just go on the `Function.prototype`. Conceptually it's on the `Function.prototype` and the more native it moves into bundlers and then in the browser it will be.

It's also important semantically because you should be getting all information about the reference from `this` and not anything from the closure. Native functions aren't bound to anything.

Code after:
    });
  }
}

export function registerServerReference<T: Function>(
  reference: T,
  id: ServerReferenceId,
  encodeFormAction?: EncodeFormActionCallback,
): ServerReference<T> {
  registerBoundServerReference(reference, id, null, encodeFormAction);
  return reference;
}

// $FlowFixMe[method-unbinding]
const FunctionBind = Function.prototype.bind;
// $FlowFixMe[method-unbinding]
const ArraySlice = Array.prototype.slice;
function bind(this: Function): Function {
  const referenceClosure = knownServerReferences.get(this);

  if (!referenceClosure) {
    // $FlowFixMe[prop-missing]
    return FunctionBind.apply(this, arguments);
  }

  const newFn = referenceClosure.originalBind.apply(this, arguments);

  if (__DEV__) {
    const thisBind = arguments[0];
    if (thisBind != null) {
      // This doesn't warn in browser environments since it's not instrumented outside
      // usedWithSSR. This makes this an SSR only warning which we don't generally do.
      // TODO: Consider a DEV only instrumentation in the browser.
      console.error(
        'Cannot bind "this" of a Server Action. Pass null or undefined as the first argument to .bind().',
      );
    }
  }

  const args = ArraySlice.call(arguments, 1);
  let boundPromise = null;
  if (referenceClosure.bound !== null) {
    boundPromise = Promise.resolve((referenceClosure.bound: any)).then(
      boundArgs => boundArgs.concat(args),
    );
  } else {
    boundPromise = Promise.resolve(args);
  }

  knownServerReferences.set(newFn, {
    id: referenceClosure.id,