[Solved] Uncaught TypeError: Cannot read property 'state or props' of undefined
The issue Cannot read the property of undefined is quite common in JavaScript. When the variable is not defined, JavaScript can not read the undefined variable or property. A similar issue we can find in React JS. We analyse the issue and try to find a solution.
1. console.log(this.state.term)
class SearchBar extends React.Component { state = { term: '' }; onFormSubmit(event) { event.preventDefault(); //What is 'preventDefault' console.log('onFormSubmit : ', this.state.term); } render() { console.log('SearchBar this.state', this) return ( <div className="ui segment"> <form onSubmit={this.onFormSubmit} className="ui form"> <div className="field"> <label>Image Search</label> <input type="text" value={this.state.term} onChange={(e) => this.setState({ term: e.target.value})} /> </div> </form> </div> ) }
This is the error that we see in the browser.
It means that this.state is ‘undefined’, therefore we just put ‘this.state’ on console.log and check what comes out.
Solution:
1. Constructor, this.bind. Because it runs only once, now the function is bound only once, this is called context-binding in the constructor, this approach is preferable, won’t be reallocated on each render.
class SearchBar extends React.Component { constructor(props) { super(props) this.state = { term: ''} this.onFormSubmit = this.onFormSubmit.bind(this) } onFormSubmit(event) { event.preventDefault(); //What is 'preventDefault' console.log('onFormSubmit : ', this); } render() { console.log('SearchBar this.state', this) return ( <div className="ui segment"> <form onSubmit={this.onFormSubmit} className="ui form"> <div className="field"> <label>Image Search</label> <input type="text" value={this.state.term} onChange={(e) => this.setState({ term: e.target.value})} /> </div> </form> </div> ) }
Now we can see an instance of SearchBar class.
2. Arrow function expression(ES6). Arrow functions inherit the binding context of their enclosing scope. basically, they don’t have ‘this’ binding, ‘this’ keyword inside references the class instance.
class SearchBar extends React.Component { constructor(props) { super(props) this.state = { term: ''} this.onFormSubmit = this.onFormSubmit.bind(this) } onFormSubmit = (event) => { event.preventDefault(); //What is 'preventDefault' console.log('onFormSubmit : ', this); } render() { console.log('SearchBar this.state', this) return ( <div className="ui segment"> <form onSubmit={this.onFormSubmit} className="ui form"> <div className="field"> <label>Image Search</label> <input type="text" value={this.state.term} onChange={(e) => this.setState({ term: e.target.value})} /> </div> </form> </div> ) }
Again the instance of SearchBar class!