Last updated: Apr 7, 2024
Reading time·2 min
The "Cannot read property 'props' of undefined" error occurs when a class
method is called without having the correct context bound to the this
keyword.
To solve the error, define the class method as an arrow function or use the
bind
method in the classes' constructor method.
Here is an example of how the error occurs.
import React, {Component} from 'react'; class App extends Component { logProps() { // ⛔️ Uncaught TypeError: Cannot read properties of undefined (reading 'props') console.log(this.props); } render() { return ( <div> <button onClick={this.logProps}>Log props</button> </div> ); } } export default App;
Notice that we defined the logProps
method, but we haven't bound the context
of the this
keyword.
this
keyword in the logProps
method has a value of undefined
.To solve the error, switch the logProps
method to use an arrow function
instead.
import React, {Component} from 'react'; class App extends Component { // 👇️ now using arrow function logProps = () => { console.log(this.props); }; render() { return ( <div> <button onClick={this.logProps}>Log props</button> </div> ); } } export default App;
This works because arrow functions use the this
keyword of the enclosing
scope - in our example, the enclosing scope is the specific component instance.
this
keyword in functional componentsIf you are getting the error in a functional component, make sure you aren't
accessing props
using the this
keyword, e.g. use props.myProp
instead of
this.props.myProp
.
function Button(props) { return ( <button onClick={() => console.log('button clicked')}> {props.text} </button> ); } function App() { return ( <div> <Button text="Click" /> </div> ); } export default App;
Notice that the Button
component uses props.text
to access the text
prop
that was passed to it.
Alternatively, you can destructure the prop to not have to access it on the
props
object.
function Button({text}) { return ( <button onClick={() => console.log('button clicked')}> {text} </button> ) } function App() { return ( <div> <Button text="Click" /> </div> ); } export default App;
We destructured the text
property from the props
object, so the Button
component can now access it directly.
You can do this for as many props as necessary.
function Button({text, disabled}) { return ( <button disabled={disabled} onClick={() => console.log('button clicked')}> {text} </button> ); } function App() { return ( <div> <Button text="Click" disabled={false} /> </div> ); } export default App;