This error occurs when attempting to destructure properties from props that are undefined or null in a React function component. It typically happens when parent components fail to pass expected props or when components try to access nested properties before the data is available.
This error occurs when React attempts to destructure properties from a props object that is undefined or null. When you use destructuring syntax like `const { name, age } = props` or directly in function parameters like `function MyComponent({ name, age })`, JavaScript expects the value being destructured to be an object. If it's undefined or null, the destructuring operation fails. This commonly happens in function components when: - A parent component doesn't pass the expected props - Props are passed conditionally and the component renders before they're available - There's a typo in the prop name being destructured - Nested props are accessed before the parent object exists (e.g., `const { user.name } = props` when user is undefined) The error is a JavaScript TypeError, not specific to React, but it frequently appears in React applications due to the component-based architecture where data flows through props.
The most straightforward fix is to provide default values directly in the destructuring syntax. This ensures that even if props are undefined, your component has fallback values:
// Before (causes error)
function UserProfile({ name, age, email }) {
return <div>{name} - {age}</div>;
}
// After (safe with defaults)
function UserProfile({ name = 'Guest', age = 0, email = '' }) {
return <div>{name} - {age}</div>;
}For the entire props object being undefined, use a fallback empty object:
function UserProfile({ name, age } = {}) {
return <div>{name || 'Guest'} - {age || 0}</div>;
}For nested props or complex objects, use optional chaining (?.) and nullish coalescing (??) operators:
function UserProfile(props) {
const name = props?.user?.name ?? 'Guest';
const age = props?.user?.age ?? 0;
return (
<div>
<h1>{name}</h1>
<p>Age: {age}</p>
</div>
);
}Or with destructuring:
function UserProfile({ user = {} }) {
const { name = 'Guest', age = 0 } = user;
return <div>{name} - {age}</div>;
}Check that the parent component is actually passing the props your child expects:
// Parent component - make sure props are passed
function ParentComponent() {
const userData = { name: 'John', age: 30 };
// Correct - passes props as attributes
return <UserProfile name={userData.name} age={userData.age} />;
// Or spread the object
return <UserProfile {...userData} />;
// Incorrect - passes nothing
// return <UserProfile />;
}Use React DevTools to inspect the props being received by the failing component and confirm they match what's expected.
If props come from async operations (API calls, database queries), add loading states:
function UserProfile({ user }) {
// Guard clause for undefined data
if (!user) {
return <div>Loading user data...</div>;
}
const { name, age, email } = user;
return (
<div>
<h1>{name}</h1>
<p>{age} years old</p>
<p>{email}</p>
</div>
);
}
// In parent component
function App() {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUserData().then(data => setUser(data));
}, []);
return <UserProfile user={user} />;
}If using TypeScript, define explicit interfaces to catch prop issues at compile time:
interface UserProfileProps {
name: string;
age: number;
email?: string; // Optional prop
}
function UserProfile({ name, age, email = '' }: UserProfileProps) {
return (
<div>
<h1>{name}</h1>
<p>{age} years old</p>
{email && <p>{email}</p>}
</div>
);
}
// TypeScript will error if parent doesn't pass required props
function Parent() {
// Error: Property 'age' is missing
// return <UserProfile name="John" />;
// Correct
return <UserProfile name="John" age={30} />;
}PropTypes for Runtime Validation
While defaultProps has been deprecated in function components (as of React 18.3+), you can still use prop-types library for runtime validation during development:
import PropTypes from 'prop-types';
function UserProfile({ name, age }) {
return <div>{name} - {age}</div>;
}
UserProfile.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired
};
UserProfile.defaultProps = {
name: 'Guest',
age: 0
};Context API Considerations
When using React Context, ensure the component is wrapped in the provider:
// Wrong - Consumer outside provider
function App() {
return <UserProfile />; // user context is undefined
}
// Correct - Consumer inside provider
function App() {
return (
<UserContext.Provider value={{ name: 'John', age: 30 }}>
<UserProfile />
</UserContext.Provider>
);
}
function UserProfile() {
const { name, age } = useContext(UserContext) || {};
return <div>{name} - {age}</div>;
}React Router Props
If using React Router v6+, props are no longer automatically injected. Use hooks instead:
// Old (v5) - props injected automatically
function UserProfile({ match, history, location }) {
const { userId } = match.params;
}
// New (v6) - use hooks explicitly
import { useParams, useNavigate, useLocation } from 'react-router-dom';
function UserProfile() {
const { userId } = useParams();
const navigate = useNavigate();
const location = useLocation();
}Performance Note: Using default parameter values (= {}) creates a new object on every render. For optimal performance with deeply nested default values, consider useMemo or define defaults outside the component.
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
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
Vite HMR connection failed, make sure your config is correct
How to fix "Vite HMR connection failed" in React