logoESLint React
Rules

unsupported-syntax

Full Name in @eslint-react/eslint-plugin@beta

@eslint-react/unsupported-syntax

Full Name in eslint-plugin-react-x@beta

react-x/unsupported-syntax

Presets

x recommended recommended-typescript recommended-type-checked strict strict-typescript strict-type-checked

Description

Validates against syntax that React Compiler does not support. If you need to, you can still use this syntax outside of React, such as in a standalone utility function.

React Compiler needs to statically analyze your code to apply optimizations. Features like eval, with, and immediately-invoked function expressions (IIFEs) in JSX make it impossible or impractical for the compiler to statically understand what the code does at compile time, so the compiler can't optimize components that use them.

This rule checks for the following unsupported patterns:

  • eval — Dynamic code evaluation cannot be statically analyzed.
  • with statements — Dynamically changes scope, preventing static analysis.
  • IIFEs in JSX — Immediately-invoked function expressions within JSX elements or fragments will not be optimized by React Compiler.

Invalid

// ❌ Using eval in component
function Component({ code }) {
  const result = eval(code); // Can't be analyzed
  return <div>{result}</div>;
}
// ❌ Using with statement
function Component() {
  with (Math) { // Changes scope dynamically
    return <div>{sin(PI / 2)}</div>;
  }
}
// ❌ Dynamic property access with eval
function Component({ propName }) {
  const value = eval(`props.${propName}`);
  return <div>{value}</div>;
}
// ❌ IIFE in JSX
function MyComponent() {
  return (
    <SomeJsx>
      {(() => {
        const filteredThings = things.filter(callback);

        if (filteredThings.length === 0) {
          return <Empty />;
        }

        return filteredThings.map((thing) => <Thing key={thing.id} data={thing} />);
      })()}
    </SomeJsx>
  );
}

Valid

// ✅ Use normal property access
function Component({ propName, props }) {
  const value = props[propName]; // Analyzable
  return <div>{value}</div>;
}
// ✅ Use standard Math methods
function Component() {
  return <div>{Math.sin(Math.PI / 2)}</div>;
}
// ✅ eval outside of components and hooks is fine
function notAComponent() {
  const result = eval("1 + 2");
  return result;
}
// ✅ Extract IIFE logic into a variable before JSX
function MyComponent() {
  const thingsList = (() => {
    const filteredThings = things.filter(callback);

    if (filteredThings.length === 0) {
      return <Empty />;
    }

    return filteredThings.map((thing) => <Thing key={thing.id} data={thing} />);
  })();

  return (
    <SomeJsx>
      {thingsList}
    </SomeJsx>
  );
}
// ✅ Use useMemo instead of IIFE
function MyComponent() {
  const thingsList = useMemo(() => {
    const filteredThings = things.filter(callback);

    if (filteredThings.length === 0) {
      return <Empty />;
    }

    return filteredThings.map((thing) => <Thing key={thing.id} data={thing} />);
  }, [things, callback]);

  return (
    <SomeJsx>
      {thingsList}
    </SomeJsx>
  );
}

Troubleshooting

I need to evaluate dynamic code

You might need to evaluate user-provided code:

// ❌ Wrong: eval in component
function Calculator({ expression }) {
  const result = eval(expression); // Unsafe and unoptimizable
  return <div>Result: {result}</div>;
}

Use a safe expression parser instead:

// ✅ Better: Use a safe parser
import { evaluate } from 'mathjs'; // or similar library

function Calculator({ expression }) {
  const [result, setResult] = useState(null);
  const calculate = () => {
    try {
      // Safe mathematical expression evaluation
      setResult(evaluate(expression));
    } catch (error) {
      setResult('Invalid expression');
    }
  };
  return (
    <div>
      <button onClick={calculate}>Calculate</button>
      {result && <div>Result: {result}</div>}
    </div>
  );
}

Note: Never use eval with user input — it's a security risk. Use dedicated parsing libraries for specific use cases like mathematical expressions, JSON parsing, or template evaluation.

I need conditional rendering logic in JSX

You might be using an IIFE in JSX to handle complex conditional rendering:

// ❌ Wrong: IIFE in JSX
function MyComponent() {
  return (
    <div>
      {(() => {
        if (loading) return <Spinner />;
        if (error) return <Error />;
        return <Content />;
      })()}
    </div>
  );
}

Extract the logic into a variable before the return statement, or use a helper component:

// ✅ Better: Extract into a variable
function MyComponent() {
  const content = (() => {
    if (loading) return <Spinner />;
    if (error) return <Error />;
    return <Content />;
  })();

  return <div>{content}</div>;
}
// ✅ Even better: Use ternary or logical expressions
function MyComponent() {
  return (
    <div>
      {loading ? <Spinner /> : error ? <Error /> : <Content />}
    </div>
  );
}

Examples

Failing

function Component({ code }) {
  const result = eval(code);
  //             ^^^^^^^^^^
  //             - Do not use 'eval' inside components or hooks. 'eval' cannot be statically analyzed
  //               and is not supported by React Compiler.
  return <div>{result}</div>;
}
function Component() {
  with (Math) {
  // ^^^^^^^^^^
  // - Do not use 'with' statements inside components or hooks. 'with' changes scope dynamically
  //   and is not supported by React Compiler.
    return <div>{sin(PI / 2)}</div>;
  }
}
function useMyHook(code) {
  const result = eval(code);
  //             ^^^^^^^^^^
  //             - Do not use 'eval' inside components or hooks. 'eval' cannot be statically analyzed
  //               and is not supported by React Compiler.
  return result;
}
function MyComponent() {
  return (
    <SomeJsx>
      {(() => {
      // ^^^^^^^
      // - Avoid using immediately-invoked function expressions in JSX. IIFEs will not be optimized
      //   by React Compiler.
        const filteredThings = things.filter(callback);

        if (filteredThings.length === 0) {
          return <Empty />;
        }

        return filteredThings.map((thing) => <Thing key={thing.id} data={thing} />);
      })()}
    </SomeJsx>
  );
}

Passing

function Component({ propName, props }) {
  const value = props[propName];
  return <div>{value}</div>;
}
function Component() {
  return <div>{Math.sin(Math.PI / 2)}</div>;
}
function Component() {
  const handleClick = () => {
    eval("something");
  };
  return <button onClick={handleClick}>Click</button>;
}
function Component() {
  useEffect(() => {
    eval("something");
  }, []);
  return <div>Content</div>;
}
function MyComponent() {
  const thingsList = useMemo(() => {
    const filteredThings = things.filter(callback);

    if (filteredThings.length === 0) {
      return <Empty />;
    }

    return filteredThings.map((thing) => <Thing key={thing.id} data={thing} />);
  }, [things, callback]);

  return (
    <SomeJsx>
      {thingsList}
    </SomeJsx>
  );
}

Implementation

Further Reading

On this page