Skip to content

Latest commit

 

History

History
80 lines (65 loc) · 2.12 KB

README.md

File metadata and controls

80 lines (65 loc) · 2.12 KB

react-compiler-bug

How to run

# Install dependencies:
npm install
# Install dependencies:
node ./index.js

Description

If a nested method shorthand syntax is used in a component that returns an arrow function, it will prevent React's compiler optimizations. However, if the arrow function is used directly, the optimizations work as expected.

The Problem

The returnsNonNode(...) function detects the return type of nested functions incorrectly, causing the compiler to mistakenly interpret them as non-Component functions.

Link for code

function returnsNonNode(
  node: NodePath<
    t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
  >,
): boolean {
  let hasReturn = false;
  let returnsNonNode = false;

  node.traverse({
    ReturnStatement(ret) {
      hasReturn = true;
      const argument = ret.node.argument;
      if (argument == null) {
        returnsNonNode = true;
      } else {
        switch (argument.type) {
          case 'ObjectExpression':
          case 'ArrowFunctionExpression':
          case 'FunctionExpression':
          case 'BigIntLiteral':
          case 'ClassExpression':
          case 'NewExpression': // technically `new Array()` is legit, but unlikely
            returnsNonNode = true;
        }
      }
    },
    ArrowFunctionExpression: skipNestedFunctions(node),
    FunctionExpression: skipNestedFunctions(node),
    FunctionDeclaration: skipNestedFunctions(node),
  });

  return !hasReturn || returnsNonNode;
}

Example

import React from 'react';

const TestContext = React.createContext({});

export function Test() {
    const context = {
        foo: 'fsd',
        testFn() {  // if it is an arrow function its work
            return () => 'test'; // it will break compile if returns an arrow fn 
        },
        bar: 'bar'
    };

    return (
        <TestContext.Provider value={context}>
            <div>Not Compiled </div>
        </TestContext.Provider>
    );
}