Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this.state is undefined in react native?

Tags:

I am a complete newbie in react native, react.js, and javascript. I am Android developer so would like to give RN a try.

Basically, the difference is in onPress;

This code shows 'undefined' when toggle() runs:

class LoaderBtn extends Component {     constructor(props) {         super(props);         this.state = { loading: false };     }      toggle() {         console.log(this.state);         // let state = this.state.loading;         console.log("Clicked!")         // this.setState({ loading: !state })     }      render() {         return (             <Button style={{ backgroundColor: '#468938' }} onPress={this.toggle}>                 <Text>{this.props.text}</Text>             </Button>         );     } } 

but this code works:

class LoaderBtn extends Component {     constructor(props) {         super(props);         this.state = { loading: false };     }      toggle() {         console.log(this.state);         // let state = this.state.loading;         console.log("Clicked!")         // this.setState({ loading: !state })     }      render() {         return (             <Button style={{ backgroundColor: '#468938' }} onPress={() => {this.toggle()}}>                 <Text>{this.props.text}</Text>             </Button>         );     } } 

Can you explain me the difference, please?

In Java / Kotlin we have method references, basically it passes the function if signatures are the same, like onPress = () => {} and toggle = () => {}

But in JS it doesn't work :(

like image 302
Nikita Kraev Avatar asked Mar 28 '17 16:03

Nikita Kraev


People also ask

What is undefined In React Native?

To check for undefined in React, use a comparison to check if the value is equal or is not equal to undefined , e.g. if (myValue === undefined) {} or if (myValue !== undefined) {} . If the condition is met, the if block will run.

Why is this undefined In React event handler?

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.

Can't access property state _this is undefined?

The "cannot read property 'setState' 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.

Why is React not updating on state change?

State updates in React are asynchronous; when an update is requested, there is no guarantee that the updates will be made immediately. The updater functions enqueue changes to the component state, but React may delay the changes, updating several components in a single pass.


2 Answers

The issue that in the first example toggle() is not bound to the correct this.

You can either bind it in the ctor:

constructor(props) {     super(props);     this.toggle = this.toggle.bind(this);     ... 

Or use an instance function (OK under some circumstances):

toggle = () => {     ... } 

This approach requires build changes via stage-2 or transform-class-properties.

The caveat with instance property functions is that there's a function created per-component. This is okay if there aren't many of them on the page, but it's something to keep in mind. Some mocking libraries also don't deal with arrow functions particularly well (i.e., arrow functions aren't on the prototype, but on the instance).

This is basic JS; this article regarding React Binding Patterns may help.

like image 156
Dave Newton Avatar answered Sep 28 '22 05:09

Dave Newton


I think what is happening is a matter of scope. When you use onPress={this.toggle} this is not what you are expecting in your toggle function. However, arrow functions exhibit different behavior and automatically bind to this. You can also use onPress={this.toggle.bind(this)}.

Further reading -

ES6 Arrow Functions

.bind()

like image 39
larz Avatar answered Sep 28 '22 04:09

larz