Semih Özden
Semih Özden

Reputation: 227

TypeError: this is undefined?

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

Answers (2)

romellem
romellem

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

Domino987
Domino987

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

Related Questions