Reputation: 227
I cannot reach this.state or I cannot setState
inside the componentDidMount
function. Why?
import React from 'react';
class LoginApi extends React.Component {
constructor(props) {
super(props);
this.state = {
formNames: [],
};
}
componentDidMount() {
let apiKey = '###';
window.JF.initialize({ apiKey: apiKey });
window.JF.login(
function success() {
window.JF.getForms(function(response) {
for (var i in response) {
this.setState({ formNames: [...this.state.formNames, response[i]] });
}
});
},
function error() {
window.alert('Could not authorize user');
}
);
}
render() {
return (
<div className="initializeForm">
<ul>
{this.state.formNames.map(forms => (
<li key={forms}>{forms}</li>
))}
</ul>
</div>
);
}
}
export default LoginApi;
When I have tried to this code I am getting TypeError: this is undefined.
this.setState({formNames: [...this.state.formNames,response[i]]});
Upvotes: 4
Views: 2622
Reputation: 6491
Because you are referencing this
within another function. When you create your callback function in JF.login
and again in JF.getForms
with the function keyword, it creates a new this
context, hence why setState
is undefined.
A common way to fix this is by using an arrow function (=>
), which will end up using the this
from its enclosing lexical scope, which in your case is the class.
window.JF.login(
() => {
window.JF.getForms((response) => {
for (var i in response) {
this.setState({ formNames: [...this.state.formNames, response[i]] });
}
});
},
() => {
window.alert('Could not authorize user');
}
);
Upvotes: 5
Reputation: 8774
Because you write the success function without bind / not as an arrow function. Without it, this refers to the calling function. In this case, to the success function. Change it to an arrow function and it will work. () => {...}
Upvotes: 4