How to fix TypeError: this.props is not an object in React

ReactBEGINNERMEDIUMUpdated Dec 10, 2025· 127 views

This error occurs when trying to access props in a React class component where the this context is undefined or not properly bound. Most commonly happens in event handlers or methods that have lost their binding to the component instance.

Quick fix

Fixes TypeError: this.props is not an object

class MyComponent extends React.Component {
  // Uses this.props
}
  1. Identify whether you are using a class or functional component
  2. For class components: Use arrow functions for event handlers
  3. Alternative: Bind methods in the constructor
  4. Ensure super(props) is called in constructor
react — error
class MyComponent extends React.Component {
// Uses this.props
}
TypeError: this.props is not an object

What this error means

This error indicates that the `this` keyword inside a class component method is not referring to the component instance as expected, making `this.props` undefined or not an object. In React class components, the `this` context must be properly bound to the component instance to access props, state, and other instance methods. When a method is called without the correct context—such as when passed as an event handler—the `this` keyword may be undefined, causing this error when attempting to access `this.props`. This issue is specific to ES6 class components, as React no longer autobinds methods like it did in earlier versions using `React.createClass`. Understanding JavaScript's `this` binding behavior is crucial for debugging this error.

Typical symptoms

  • Error appears when clicking buttons or triggering event handlers
  • Methods work in render() but fail when called as callbacks
  • Console shows "Cannot read property 'props' of undefined"
  • App crashes when trying to access this.props in event handlers
  • Props are accessible in constructor and render but not in custom methods

Common causes

  1. Event handler methods not bound to component instance in class constructor
  2. Using this keyword in functional components instead of props parameter
  3. Forgetting to call super(props) in class component constructor
  4. Passing class methods as callbacks without binding them
  5. Arrow functions in render creating new function instances on each render
  6. Trying to access this.props before constructor completes when super(props) is missing

How to fix "TypeError: this.props is not an object"

1Identify whether you are using a class or functional component

First, determine your component type:

Class component:

jsx
class MyComponent extends React.Component {
  // Uses this.props
}

Functional component:

jsx
function MyComponent(props) {
  // Uses props directly (no "this")
}

If you're using a functional component, you should never use this.props. Use the props parameter instead or destructure it:

jsx
function MyComponent({ name, onClick }) {
  return <button onClick={onClick}>{name}</button>;
}
2For class components: Use arrow functions for event handlers

The recommended approach is to define event handlers as arrow functions, which automatically bind to the component instance:

jsx
class MyComponent extends React.Component {
  // Arrow function binds 'this' automatically
  handleClick = () => {
    console.log(this.props.message); // Works correctly
  }

  render() {
    return <button onClick={this.handleClick}>Click me</button>;
  }
}

Arrow functions use lexical this binding, meaning they inherit this from the enclosing scope (the component instance).

3Alternative: Bind methods in the constructor

If you prefer traditional methods, bind them in the constructor:

jsx
class MyComponent extends React.Component {
  constructor(props) {
    super(props); // Always call super(props) first

    // Bind methods in constructor
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    console.log(this.props.message); // Now works correctly
  }

  render() {
    return <button onClick={this.handleClick}>Click me</button>;
  }
}

This approach is recommended in the React documentation for better performance, as the binding only happens once during initialization.

4Ensure super(props) is called in constructor

If you have a constructor, always call super(props) before accessing this.props:

jsx
class MyComponent extends React.Component {
  constructor(props) {
    super(props); // REQUIRED - passes props to parent class
    console.log(this.props); // Now defined
  }
}

Without passing props to super(), this.props will be undefined inside the constructor until it completes. If you don't need to use this.props in the constructor, you can omit the constructor entirely.

5Avoid inline arrow functions in render for performance

While you can bind using inline arrow functions, this creates a new function on every render:

jsx
// Works but not optimal (creates new function each render)
<button onClick={() => this.handleClick()}>Click me</button>

// Better: Use class arrow function or constructor binding
<button onClick={this.handleClick}>Click me</button>

Inline arrow functions can cause performance issues and unnecessary re-renders in child components, especially in lists or frequently updating components.

Advanced notes

Context Loss Patterns:

The error commonly occurs in these scenarios:

1. Event handlers: <button onClick={this.handleClick}> - The method reference loses its this binding
2. Callback functions: setTimeout(this.doSomething, 1000) - Similar binding loss
3. Array methods: items.map(this.renderItem) - Each iteration may lose context

Migration to Hooks:

If you're encountering this error frequently, consider migrating to functional components with hooks, which avoid the entire this binding problem:

jsx
// Old class component with binding issues
class MyComponent extends React.Component {
  handleClick = () => {
    console.log(this.props.message);
  }
  render() {
    return <button onClick={this.handleClick}>Click</button>;
  }
}

// Modern functional component (no binding needed)
function MyComponent({ message }) {
  const handleClick = () => {
    console.log(message);
  };
  return <button onClick={handleClick}>Click</button>;
}

Performance Considerations:

- Constructor binding: Best performance, binding happens once
- Arrow class properties: Good performance, requires babel plugin
- Inline arrow functions: Worst performance, new function every render
- bind() in render: Also creates new function every render, avoid

TypeScript Considerations:

TypeScript can help catch these errors at compile time by enforcing proper this types. Enable strictBindCallApply and noImplicitThis in your tsconfig.json for better type safety.

Frequently asked questions

What does "TypeError: this.props is not an object" mean?
props undefined or not an object. In React class components, the this context must be properly bound to the component instance to access props, state, and other instance methods. props.
How do I fix "TypeError: this.props is not an object"?
This error occurs when trying to access props in a React class component where the this context is undefined or not properly bound. Most commonly happens in event handlers or methods that have lost their binding to the component instance.
What causes "TypeError: this.props is not an object"?
Event handler methods not bound to component instance in class constructor Using this keyword in functional components instead of props parameter Forgetting to call super(props) in class component constructor
Is the "TypeError: this.props is not an object" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading