This error occurs when explicitly setting defaultProps to undefined in React components. While defaultProps is meant to provide fallback values for missing props, setting them to undefined defeats this purpose and can cause runtime issues.
This error typically appears when developers try to set a component's defaultProps to undefined values. In React, defaultProps are used to provide fallback values when props are not provided by the parent component. However, setting a defaultProp to undefined is problematic because it doesn't actually provide a default value - it just passes undefined through. The core issue is that defaultProps only apply when a prop is missing or explicitly passed as undefined from the parent. When you define a defaultProp as undefined, you're essentially saying "the default value is no value," which defeats the purpose of having defaults. This can lead to runtime errors when your component logic expects actual values, especially in TypeScript projects with strict null checking. React 18.3+ has deprecated defaultProps for function components entirely, encouraging developers to use ES6 default parameters instead, which makes this pattern even more problematic in modern React applications.
Review your component's defaultProps and replace any undefined values with meaningful defaults:
// ❌ Bad - undefined doesn't provide a default
MyComponent.defaultProps = {
label: undefined,
count: undefined,
};
// ✅ Good - actual default values
MyComponent.defaultProps = {
label: 'Default Label',
count: 0,
};If a prop truly doesn't need a default value, simply omit it from defaultProps entirely.
For function components, migrate from defaultProps to ES6 default parameters (the modern approach):
// ❌ Old pattern (deprecated in React 18.3+)
function MyComponent({ label, count }) {
return <div>{label}: {count}</div>;
}
MyComponent.defaultProps = {
label: 'Default',
count: 0,
};
// ✅ Modern pattern
function MyComponent({
label = 'Default',
count = 0
}) {
return <div>{label}: {count}</div>;
}This approach is clearer, has better TypeScript support, and avoids deprecation warnings.
If you need conditional defaults based on runtime logic, use nullish coalescing within the component:
function MyComponent({ label, count }) {
// Use ?? to provide defaults only when undefined or null
const displayLabel = label ?? 'Default Label';
const displayCount = count ?? 0;
return <div>{displayLabel}: {displayCount}</div>;
}This gives you more flexibility than defaultProps and works consistently across React versions.
Ensure your TypeScript prop types align with your default value strategy:
// ❌ Type suggests label might be undefined, but default prevents that
interface Props {
label?: string | undefined;
count?: number;
}
// ✅ Use default parameters and adjust types accordingly
interface Props {
label?: string; // Will always have a value due to default
count?: number;
}
function MyComponent({
label = 'Default',
count = 0
}: Props) {
// TypeScript knows these are never undefined
return <div>{label.toUpperCase()}: {count}</div>;
}If you're on React 18.3 or later, remove defaultProps from function components to eliminate deprecation warnings:
// Before
const MyComponent = ({ label, count }) => {
return <div>{label}: {count}</div>;
};
MyComponent.defaultProps = {
label: 'Default',
count: 0,
};
// After
const MyComponent = ({
label = 'Default',
count = 0
}) => {
return <div>{label}: {count}</div>;
};Note: defaultProps still work for class components, but the ES6 approach is preferred for consistency.
defaultProps vs null vs undefined behavior:
React treats missing props and explicitly passed undefined props the same way - both trigger defaultProps. However, explicitly passing null does NOT trigger defaultProps:
// These trigger defaultProps:
<MyComponent />
<MyComponent label={undefined} />
// This does NOT trigger defaultProps:
<MyComponent label={null} />TypeScript limitations with defaultProps:
TypeScript's type system has known limitations when working with defaultProps. Even with defaultProps set, TypeScript in strict mode may still flag props as possibly undefined. This is one reason the React team deprecated defaultProps for function components - ES6 defaults provide better type inference.
Class component considerations:
For class components, defaultProps remain supported. You can define them as a static property:
class MyComponent extends React.Component {
static defaultProps = {
label: 'Default',
count: 0,
};
render() {
return <div>{this.props.label}: {this.props.count}</div>;
}
}ESLint configuration:
If you're using ESLint with eslint-plugin-react, you can enable the react/require-default-props rule to catch undefined defaultProps. However, consider disabling this rule if you're using ES6 defaults instead:
{
"rules": {
"react/require-default-props": "off"
}
}React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite