I want to modify a component's state (react native) after a promise is resolved.
Here is my code:
class Greeting extends Component{
constructor(props){
super(props);
this.state = {text: 'Starting...'};
var handler = new RequestHandler();
handler.login('email','password')
.then(function(resp){
this.setState({text:resp});
});
}
render(){
return (
<Text style={this.props.style}>
Resp: {this.state.text}
</Text>
);
}
}
But when the promise resolve, it throws the following error:
this.setState is not a function
TypeError: this.setState is not a function
at http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:1510:6
at tryCallOne (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:25187:8)
at http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:25273:9
at JSTimersExecution.callbacks.(anonymous function) (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:8848:13)
at Object.callTimer (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:8487:1)
at Object.callImmediatesPass (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:8586:19)
at Object.callImmediates (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:8601:25)
at http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:7395:43
at guard (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:7288:1)
at MessageQueue.__callImmediates (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:7395:1)
How can I change the current Component state after a promise is resolved?
So, when you mutate the state directly and call setState() with an empty object. The previous state will be polluted with your mutation. Due to which, the shallow compare and merge of two states will be disturbed or won't happen, because you'll have only one state now.
componentDidMount() invokes immediately after a component mounts. You can call setState() immediately in componentDidMount() and triggers an extra rendering, but this happens before the browser updates the screen, calling render() twice.
When you directly update the state, it does not change this. state immediately. Instead, it creates a pending state transition, and accessing it after calling this method will only return the present value. You will lose control of the state across all components.
The callback has a different context than the object you are working with. For this reason, this
is not what you think it is.
To solve this, you can use an arrow function, which keeps the surrounding context:
constructor(props){
super(props);
this.state = {text: 'Starting...'};
var handler = new RequestHandler();
handler.login('email','password')
.then(resp => this.setState({text:resp}));
}
Alternatively, set the function context manually using bind()
:
constructor(props){
super(props);
this.state = {text: 'Starting...'};
var handler = new RequestHandler();
handler.login('email','password')
.then(function(resp){
this.setState({text:resp});
}.bind(this));
}
It's better to use new syntax. more here https://babeljs.io/blog/2015/06/07/react-on-es6-plus
class Greeting extends Component{
state = {
text: 'Starting...',
}
componentDidMount() {
var handler = new RequestHandler();
handler.login('email','password')
.then((text) => {
this.setState({ text });
})
}
render(){
return (
<Text style={this.props.style}>
Resp: {this.state.text}
</Text>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With