In strict mode, however, if the value of this is not set when entering an execution context, it remains as undefined, as shown in the following example Inside of arrow functions, the value of this is taken from the surrounding scope that the arrow function was declared in. In your case, that is the top level of your module, so this takes on the value of undefined. Also, note that you might get different behavior from sections of script defined inside modules as opposed to in standard scripts. This is because modules use strict mode automatically
There are a couple of ways to deal with it.see first stackoverflow answer you
will get it.
One is to add this.onToggleLoop = this.onToggleLoop.bind(this); in the constructor.
Another is arrow functions onToggleLoop = (event) => {
...
}.
And then there is onClick = {
this.onToggleLoop.bind(this)
}.
<!-- A "module" is what react component code is usually written in -->
<script type="module">
console.log("Module code (react code) this:", this); // undefined
// ^
const App = () => { // example component |
this // --- taken from surrounding scope ---+
}
</script>
function f2() {
'use strict'; // see strict mode
return this;
}
console.log(f2() === undefined); // true
this
was used before hooks in class-based components:
class MyClass extends React.Component {
render() {
console.log(this.props, this.state);
}
}
Now, by just adding that single line in the constructor of your component, this will refer to the component within your event handler function. When I’m teaching React to developers, one thing that comes up often is dealing with a common error. But here’s the interesting thing: it’s not running into the error that comes up all the time, its how to deal with it that surprises them. I’ve always wanted to have something to point to that the scenario & why one option is better than others, even though there are plenty of ways to address the issue. That’s what this post is! In this very simple component, you are accessing a member from the class from the event handler. You think this is pointing to the Sample class, but what you get is a nasty error. TypeError: Cannot read property ‘foo’ of undefined
export default class HelloWorld extends React.Component<IHelloWorldProps, {}> {
private foo: string = "some string";
public render(): React.ReactElement<IHelloWorldProps> {
return (
<button type="button" onClick={ this.onClickHandler }>
trigger problem
</button>
);
}
private onClickHandler(): void {
console.log(`Value of 'this'`, this);
alert(`Value of foo: ${ this.foo }`);
}
}
export default class HelloWorld extends React.Component<IHelloWorldProps, {}> {
private foo: string = "some string";
constructor(props: IHelloWorldProps) {
super(props);
this.onClickHandlerBind = this.onClickHandlerBind.bind(this);
}
public render(): React.ReactElement<IHelloWorldProps> {
return (
<button type="button" onClick={ this.onClickHandlerBind }>
fixed with bind
</button>
);
}
private onClickHandlerBind(): void {
console.log(`Value of 'this'`, this);
alert(`Value of foo: ${ this.foo }`);
}
}
export default class HelloWorld extends React.Component<IHelloWorldProps, {}> {
private foo: string = "some string";
public render(): React.ReactElement<IHelloWorldProps> {
return (
<button type="button" onClick={ this.onClickHandlerArrow }>
fixed with arrow
</button>
);
}
private onClickHandlerArrow = (): void => {
console.log(`Value of 'this'`, this);
alert(`Value of foo: ${ this.foo }`);
}
}
The ‘this’ keyword in JavaScript is always being somewhat tough to understand for learners. Basically this keyword inside a function is determined by looking at how the method is actually invoked. Usually in JavaScript, we invoked the method using syntax obj.method(). In this case, the value of ‘this’ keyword inside the method function is the object ‘obj’. How we invoked the method is all root of the unpredictable value of ‘this’ often. How to bind ‘this’ keyword to resolve classical error message ‘state of undefined’ in React? In React when we use event handlers we basically give a reference of a function to that event handler and when that event occurs that function gets invoked, here’s a catch, it’s invoked at some point of time not immediately, and when its invoked, it’s invoked as its own, there is now any components instance object using which it gets invoked and that’s why the value of ‘this’ keyword inside the method is undefined. To resolve this issue we usually bind the value of ‘this’ keyword using the JavaScript bind method.
Example 1:
index.js :
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(
<App />, document.querySelector('#root'))
App.js :
import React, { Component } from 'react'
class App extends Component {
static defaultProps = {
courseContent : [
'JSX', 'React Props', 'React State',
'React Lifecycle Methods',
'React Event Handlers', 'React Router',
'React Hooks', 'Readux',
'React Context'
]
}
constructor(props){
super(props)
// Set initial state
this.state = {msg : 'React Course', content:''}
// Binding this keyword of method handleClick
this.handleClick = this.handleClick.bind(this)
}
renderContent(){
return (
<ul>
{this.props.courseContent.map(content => (
<li>{content}</li>
))}
</ul>
)
}
handleClick(){
// Changing state
this.setState({
msg : 'Course Content',
content : this.renderContent()
})
}
render(){
// Reference of handleClick, called at some
// point of time on its own gets called like
// handleClick(), thats why this inside
// handleClick is undefined
const button = !this.state.content &&
<button onClick={this.handleClick}>
Click here to know contents!
</button>
return (
<div>
<h2>Message :</h2>
<p>{this.state.msg}</p>
<p>{this.state.content}</p>
{button}
</div>
)
}
}
export default App
TodoList.js :
import React, { Component } from 'react'
import TodoForm from './TodoForm'
class TodoList extends Component{
constructor(props){
super(props)
this.state = { todos : [] }
// Binding this keyword of method createTodo
this.createTodo = this.createTodo.bind(this)
// Binding this keyword of method renderTodo
this.renderTodos = this.renderTodos.bind(this)
}
createTodo(todo){
this.setState({
todos : [...this.state.todos, todo]
})
}
renderTodos(){
const todos = this.state.todos.map(todo => (
<li key={todo}>
{todo.task}
</li>
))
return <ul>{todos}</ul>
}
render(){
return(
<div>
<h1>Todo List</h1>
{this.renderTodos()}
<TodoForm create={this.createTodo}/>
</div>
)
}
}
export default TodoList
This is because when you use an arrow function, the event handler is automatically bound to the component instance so you don’t need to bind it in the constructor. When you use an arrow function you are binding this lexically. The attribute onClick just stores a reference to that function. Whenever a user clicks on the button, that referenced function is called on the global object. So the keyword this is set to undefined in the strict mode. To resolve this, you have to bind the increaseCounter() to this in the constructor.01-Apr-2019 In React when we use event handlers we basically give a reference of a function to that event handler and when that event occurs that function gets invoked, here’s a catch, it’s invoked at some point of time not immediately, and when its invoked, it’s invoked as its own, there is now any components instance object 11-Feb-2022
In this lesson, we’ll use programming to try to solve the Why Is This Undefined In React puzzle. The code shown below demonstrates this.
There are a couple of ways to deal with it.see first stackoverflow answer you
will get it.
One is to add this.onToggleLoop = this.onToggleLoop.bind(this); in the constructor.
Another is arrow functions onToggleLoop = (event) => {
...
}.
And then there is onClick = {
this.onToggleLoop.bind(this)
}.
With React, typically you only need to bind the methods you pass to other components. For example, <button onClick={this.handleClick}> passes this.handleClick so you want to bind it. However, it is unnecessary to bind the render method or the lifecycle methods: we don’t pass them to other components. If you need to have access to the parent component in the handler, you also need to bind the function to the component instance (see below). If you have an event handler such as onClick or onScroll and want to prevent the callback from being fired too quickly, then you can limit the rate at which callback is executed. This can be done by using:
<button onClick={this.handleClick}>
class Foo extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}
class Foo extends Component {
handleClick = () => {
console.log('Click happened');
};
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}
class Foo extends Component {
handleClick() {
console.log('Click happened');
}
render() {
return <button onClick={() => this.handleClick()}>Click Me</button>;
}
}
obj.method();
You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called. This is not React-specific behavior; it is a part of how functions work in JavaScript. Generally, if you refer to a method without () after it, such as onClick={this.handleClick}, you should bind that method. If calling bind annoys you, there are two ways you can get around this. You can use public class fields syntax to correctly bind callbacks:
<button onclick="activateLasers()">
Activate Lasers
</button>
<button onClick={activateLasers}> Activate Lasers
</button>
<form onsubmit="console.log('You clicked submit.'); return false">
<button type="submit">Submit</button>
</form>
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback this.handleClick = this.handleClick.bind(this); }
handleClick() { this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn })); }
render() {
return (
<button onClick={this.handleClick}> {this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
class LoggingButton extends React.Component {
// This syntax ensures `this` is bound within handleClick. handleClick = () => { console.log('this is:', this); }; render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
We cannot tell the difference between forgetting to return and explicitly returning undefined at runtime. As linting operates at the code syntax, it can determine this difference. Not able to create a generic type for something that React can render, which we can use in place of any prop or component. It has been a long-standing issue in the ecosystem. With the changes in React 18, no runtime error will be thrown if nothing is returned from the component.
//Shape.jsx
import React from 'react';
import Circle from './Circle';
import Square from './Square';
function Shape({type}) {
if(type === 'circle') {
return <Circle />
}
if(type === 'square') {
return <Square />
}
}
export default Shape;
//App.jsx
function App() : ComponentType {
return(<Shape type="rectangle"/>)
}
//Rectangle is passed as props in type which is not handled in the Shape component, so it will throw an error
Error: Shape(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
import React from 'react';
import Circle from './Circle';
import Square from './Square';
function Shape({type}) {
if(type === 'circle') {
return <Circle />
}
if(type === 'square') {
return <Square />
}
return null;
}
export default Shape;
//Shape.jsx
const Shape = ({children}: ComponentType): ComponentType => {
return children;
}
//App.jsx
function App() : ComponentType{
return(<Shape />);
}
If you run into this error while writing React, the odds are high that you are trying to use a function within another function and are trying to access the this keyword within the nested function. But why does this happen? If you are a React developer or are just learning to program in JavaScript, you might have run into this dreaded error while trying to read a property off of the this keyword: So you've diagnosed the problem. You need to make sure that your functions have access to the this context of your class component! To do this, you can use ES6 arrow functions.
1TypeError: Cannot read property '<your property name>' of undefined
1class FishSpecies Extends React.Component {
2 constructor(props) {
3 super(props);
4 this.state = {
5 clickCount: 0
6 };
7 }
8
9 onFishClicked() {
10 this.setState(function(prevState, props) {
11 return { clickCount: prevState.clickCount + 1 };
12 });
13 }
14
15 render() {
16 return (
17 <ul>
18 {{ this.props.fish.map(function(fish) {
19 return <Fish name={fish.name} onClick={this.onFishClicked} />
20 })}}
21 </ul>
22 )
23 }
24}
1 TypeError: Cannot read property 'onFishClicked' of undefined
The last option we have is to change our increment and decrement methods to arrow function class properties. This solution appears enticing on its face, but we’ll discuss why it’s my least favorite solution after we look at the implementation: When we click the Increment or Decrement button, we’ll get an error: Cannot read property 'count' of undefined. Our console will show us that indeed it appears this.state is undefined: React components using ES6 classes do not autobind this to non-React.Component methods. That means we have no assurance that this within our increment and decrement methods refer to the instance of the React class component.
class App extends React.Component {
constructor() {
super();
this.state = {
count: 0,
};
}
increment() {
this.setState({ count: this.state.count + 1 });
}
decrement() {
this.setState({ count: this.state.count - 1 });
}
render() {
return (
<div className="App">
<h1>Counter</h1>
<div>{this.state.count}</div>
<button onClick={this.increment}>Increment</button>
<button onClick={this.decrement}>Decrement</button>
</div>
);
}
}
export default App;
class App extends React.Component {
constructor() {
super();
this.state = {
count: 0,
};
this.increment = this.increment.bind(this);
this.decrement = this.decrement.bind(this);
}
increment() {
this.setState({ count: this.state.count + 1 });
}
decrement() {
this.setState({ count: this.state.count - 1 });
}
render() {
return (
<div className="App">
<h1>Counter</h1>
<div>{this.state.count}</div>
<button onClick={this.increment}>Increment</button>
<button onClick={this.decrement}>Decrement</button>
</div>
);
}
}
export default App;
class App extends React.Component {
constructor() {
super();
this.state = {
count: 0,
};
}
increment() {
this.setState({ count: this.state.count + 1 });
}
decrement() {
this.setState({ count: this.state.count - 1 });
}
render() {
return (
<div className="App">
<h1>Counter</h1>
<div>{this.state.count}</div>
<button onClick={this.increment.bind(this)}>Increment</button>
<button onClick={this.decrement.bind(this)}>Decrement</button>
</div>
);
}
}
export default App;