Skip to main content
interlace
Plugin: react-featuresRules

no-object-type-as-default-prop

no-object-type-as-default-prop rule

Prevent object types as default prop values. This rule is part of eslint-plugin-react-features.

Quick Summary

AspectDetails
SeverityWarning (performance)
Auto-Fix❌ No (requires extraction)
CategoryReact
ESLint MCP✅ Optimized for ESLint MCP integration
Best ForReact components with object defaults

Rule Details

Using object literals as default prop values creates new object references on every render, breaking memoization and causing unnecessary re-renders.

Why This Matters

IssueImpactSolution
🔄 New reference each renderBreaks React.memo/PureComponentExtract to constant
🐛 PerformanceUnnecessary child re-rendersUse factory function
🔍 Memoization failureuseMemo/useCallback ineffectiveStable reference outside

Examples

❌ Incorrect

// BAD: Object literal creates new reference every render
function UserCard({ 
  user,
  style = { padding: 10 },           // New object every render!
  options = { animate: true },        // New object every render!
  items = []                          // New array every render!
}) {
  return <Card style={style} options={options} items={items} />;
}

The rule reports an object, array or function literal used as the default of a destructured prop of a function component (a PascalCase function that returns JSX, or a function passed to React's memo / forwardRef). A class's static defaultProps is evaluated once, when the class is defined, so it is not reported; neither is a default in a function that is not a component.

✅ Correct

// GOOD: Constants defined outside component
const DEFAULT_STYLE = { padding: 10 };
const DEFAULT_OPTIONS = { animate: true };
const EMPTY_ARRAY = [];

function UserCard({ 
  user,
  style = DEFAULT_STYLE,
  options = DEFAULT_OPTIONS,
  items = EMPTY_ARRAY
}) {
  return <Card style={style} options={options} items={items} />;
}

// Or use a factory pattern for truly dynamic defaults
function UserCard({ user, style, options }) {
  const mergedStyle = useMemo(
    () => ({ ...DEFAULT_STYLE, ...style }),
    [style]
  );
  
  return <Card style={mergedStyle} options={options} />;
}

Configuration Examples

Basic Usage

{
  rules: {
    'react-features/no-object-type-as-default-prop': 'warn'
  }
}

Further Reading

Known False Negatives

  • Other fresh values: new Map(), a regular expression literal or a class expression as a default also create a new value per render and are not reported.
  • Components the rule does not recognise: a function wrapped by a higher-order function other than React's memo / forwardRef, or one that returns JSX only through a helper call.

Not reported by design: a class's static defaultProps (evaluated once, when the class is defined) and defaults in functions that are not components.

Use this rule

npm install -D oxlint-plugin-react-features
.oxlintrc.json
{  "jsPlugins": ["oxlint-plugin-react-features"],  "rules": {    "react-features/no-object-type-as-default-prop": "error"  }}
vite.config.ts
import { defineConfig } from 'vite-plus';export default defineConfig({  lint: {    jsPlugins: ['oxlint-plugin-react-features'],    rules: {      'react-features/no-object-type-as-default-prop': 'error',    },  },});

oxlint-plugin-react-features re-exports eslint-plugin-react-features/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.