This error occurs when React tries to access the "props" property on a null or undefined object, typically due to uninitialized state, missing null checks, or accessing components after they've unmounted.
This TypeError indicates that your React application is attempting to read the "props" property from a null or undefined object. This commonly happens when a component or React element hasn't been properly initialized, when accessing component internals incorrectly, or when trying to interact with a component after it has been unmounted from the DOM. The error typically surfaces in several scenarios: accessing props before they're available, destructuring from null objects, incorrect context binding in class components, or race conditions where asynchronous operations complete after a component has unmounted. Understanding the component lifecycle and proper null handling is crucial to preventing this error.
Before accessing nested properties, ensure the parent object exists using optional chaining or conditional rendering.
// Bad - no null check
function UserProfile({ user }) {
return <div>{user.name}</div>; // Crashes if user is null
}
// Good - conditional rendering
function UserProfile({ user }) {
if (!user) {
return <div>Loading...</div>;
}
return <div>{user.name}</div>;
}
// Good - optional chaining
function UserProfile({ user }) {
return <div>{user?.name ?? 'Unknown'}</div>;
}Always initialize state with appropriate default values instead of null, especially for objects and arrays.
// Bad - null initialization
const [data, setData] = useState(null);
// Good - proper default values
const [data, setData] = useState({});
const [items, setItems] = useState([]);
const [user, setUser] = useState({ name: '', email: '' });
// For data fetching, use a loading flag
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetchUser().then(data => {
setUser(data);
setIsLoading(false);
});
}, []);
if (isLoading) return <div>Loading...</div>;
if (!user) return <div>User not found</div>;
return <div>{user.name}</div>;For class components, ensure methods are properly bound to maintain correct "this" context.
// Bad - method loses context
class MyComponent extends React.Component {
handleClick() {
console.log(this.props); // this is undefined
}
render() {
return <button onClick={this.handleClick}>Click</button>;
}
}
// Good - arrow function property
class MyComponent extends React.Component {
handleClick = () => {
console.log(this.props); // this is correctly bound
}
render() {
return <button onClick={this.handleClick}>Click</button>;
}
}
// Good - bind in constructor
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log(this.props); // this is correctly bound
}
render() {
return <button onClick={this.handleClick}>Click</button>;
}
}Clean up side effects and prevent state updates after component unmounts to avoid accessing null references.
function MyComponent() {
const [data, setData] = useState(null);
useEffect(() => {
let isMounted = true;
fetchData().then(result => {
if (isMounted) {
setData(result);
}
});
// Cleanup function
return () => {
isMounted = false;
};
}, []);
return data ? <div>{data.value}</div> : <div>Loading...</div>;
}
// For timers and intervals
function TimerComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount(c => c + 1);
}, 1000);
// Clear timer on unmount
return () => clearInterval(timer);
}, []);
return <div>{count}</div>;
}Add prop validation to catch null/undefined props early in development.
// Using PropTypes
import PropTypes from 'prop-types';
function UserCard({ user }) {
return <div>{user.name}</div>;
}
UserCard.propTypes = {
user: PropTypes.shape({
name: PropTypes.string.isRequired,
email: PropTypes.string.isRequired
}).isRequired
};
// Using TypeScript
interface User {
name: string;
email: string;
}
interface UserCardProps {
user: User;
}
function UserCard({ user }: UserCardProps) {
return <div>{user.name}</div>;
}
// With optional props
interface UserCardProps {
user?: User | null;
}
function UserCard({ user }: UserCardProps) {
if (!user) return <div>No user data</div>;
return <div>{user.name}</div>;
}Implement Error Boundaries to catch and display errors gracefully instead of crashing the entire app.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
console.error('Error caught by boundary:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return (
<div>
<h2>Something went wrong</h2>
<p>{this.state.error?.message}</p>
</div>
);
}
return this.props.children;
}
}
// Usage
function App() {
return (
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
);
}Component Lifecycle Considerations: In class components, be especially careful with lifecycle methods like componentWillUnmount. If you have ongoing async operations (API calls, timers), store references to them and cancel/cleanup in componentWillUnmount to prevent accessing component internals after unmounting.
React Strict Mode: When using React.StrictMode in development, components are intentionally double-mounted to help identify side effects. This can expose null reference issues that might not appear in production. Use this to your advantage by fixing these issues during development.
Module Federation and Multiple React Instances: If using micro-frontends or Module Federation, ensure you're not loading multiple versions of React. This can cause "Cannot read properties of null (reading 'useState')" errors. Use singleton patterns in webpack configuration to share React instances.
HOC and Ref Forwarding: When using Higher-Order Components (HOCs) that wrap your component, ensure refs are properly forwarded using React.forwardRef. Without proper ref forwarding, attempting to access component methods or properties through refs will result in null references.
Testing Considerations: When writing tests with react-test-renderer or @testing-library/react, ensure you're waiting for async operations to complete before assertions. Use waitFor or findBy queries to avoid accessing null components during async state updates.
Prop spreading could cause security issues
Prop spreading could cause security issues
Error: error:0308010C:digital envelope routines::unsupported
Error: error:0308010C:digital envelope routines::unsupported
React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render.
React Hook useEffect placed inside a condition
Hook can only be called inside the body of a function component
Hook can only be called inside the body of a function component
Rollup failed to resolve import during build
How to fix "Rollup failed to resolve import" in React