Repository: facebook/react
File: packages/react-reconciler/src/ReactFiberHooks.js (JavaScript)

Code before:
            'This will lead to bugs and errors if not fixed. ' +
            'For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n' +
            '   Previous render            Next render\n' +
            '   ------------------------------------------------------\n' +
            '%s' +
            '   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n',
          componentName,
          table,
        );
      }
    }
  }
}

function warnIfAsyncClientComponent(
  Component: Function,
  componentDoesIncludeHooks: boolean,
) {
  if (__DEV__) {
    // This dev-only check only works for detecting native async functions,
    // not transpiled ones. There's also a prod check that we use to prevent
    // async client components from crashing the app; the prod one works even
    // for transpiled async functions. Neither mechanism is completely
    // bulletproof but together they cover the most common cases.
    const prototype: Object | null = Object.getPrototypeOf(Component);
    if (prototype && prototype[Symbol.toStringTag] === 'AsyncFunction') {
      // Encountered an async Client Component. This is not yet supported,
      // except in certain constrained cases, like during a route navigation.
      const componentName = getComponentNameFromFiber(currentlyRenderingFiber);
      if (!didWarnAboutAsyncClientComponent.has(componentName)) {
        didWarnAboutAsyncClientComponent.add(componentName);

        // Check if this is a sync update. We use the "root" render lanes here
        // because the "subtree" render lanes may include additional entangled
        // lanes related to revealing previously hidden content.
        const root = getWorkInProgressRoot();
        const rootRenderLanes = getWorkInProgressRootRenderLanes();
        if (root !== null && includesBlockingLane(root, rootRenderLanes)) {
          console.error(
            'async/await is not yet supported in Client Components, only ' +
              'Server Components. This error is often caused by accidentally ' +
              "adding `'use client'` to a module that was originally written " +
              'for the server.',
          );
        } else {
          // This is a concurrent (Transition, Retry, etc) render. We don't
          // warn in these cases.
          //
          // However, Async Components are forbidden to include hooks, even
          // during a transition, so let's check for that here.
          //

Review comment (suggestion):
`Object.prototype.toString.call(Component) === '[object AsyncFunction]'` could maybe be sufficient too. A bit more old school way of checking but seems more in line with how people do brand checking today.

Code after:
            'This will lead to bugs and errors if not fixed. ' +
            'For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n' +
            '   Previous render            Next render\n' +
            '   ------------------------------------------------------\n' +
            '%s' +
            '   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n',
          componentName,
          table,
        );
      }
    }
  }
}

function warnIfAsyncClientComponent(
  Component: Function,
  componentDoesIncludeHooks: boolean,
) {
  if (__DEV__) {
    // This dev-only check only works for detecting native async functions,
    // not transpiled ones. There's also a prod check that we use to prevent
    // async client components from crashing the app; the prod one works even
    // for transpiled async functions. Neither mechanism is completely
    // bulletproof but together they cover the most common cases.
    const isAsyncFunction =
      // $FlowIgnore[method-unbinding]
      Object.prototype.toString.call(Component) === '[object AsyncFunction]';
    if (isAsyncFunction) {
      // Encountered an async Client Component. This is not yet supported,
      // except in certain constrained cases, like during a route navigation.
      const componentName = getComponentNameFromFiber(currentlyRenderingFiber);
      if (!didWarnAboutAsyncClientComponent.has(componentName)) {
        didWarnAboutAsyncClientComponent.add(componentName);

        // Check if this is a sync update. We use the "root" render lanes here
        // because the "subtree" render lanes may include additional entangled
        // lanes related to revealing previously hidden content.
        const root = getWorkInProgressRoot();
        const rootRenderLanes = getWorkInProgressRootRenderLanes();
        if (root !== null && includesBlockingLane(root, rootRenderLanes)) {
          console.error(
            'async/await is not yet supported in Client Components, only ' +
              'Server Components. This error is often caused by accidentally ' +
              "adding `'use client'` to a module that was originally written " +
              'for the server.',
          );
        } else {
          // This is a concurrent (Transition, Retry, etc) render. We don't
          // warn in these cases.
          //
          // However, Async Components are forbidden to include hooks, even