Search code examples
javascriptreactjsthiswebstormsetstate

React Cannot read property 'setState' of undefined in if-block


I am creating my first ReactJS front-end application and am running into a problem. When I try to call my setState function (or any other function for that matter) with this. before it inside an if block, I get the error.

Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined

When I call the functions inside my didComponentMount() everything is fine so I think the problem is the if block. I have tried several solutions on different questions but none have an if block so it doesn't work for me.

Function that throws error:

getFilteredTrades() {
        if(document.getElementById("switch").checked){
            fetch("http://localhost:8080/trades/filter?plaform=NintendoSwitch").then(rse => rse.json()).then(
                result => {
                    this.setState({trades: result});
                }
            )
        } else if (document.getElementById("playstation").checked) {
            fetch("http://localhost:8080/trades/filter?platform=PlayStation").then(rse => rse.json()).then(
                result => {
                    this.setState({trades: result});
                }
            )
        } else if (document.getElementById("xbox").checked) {
            fetch("http://localhost:8080/trades/filter?platform=XBox").then(rse => rse.json()).then(
                result => {
                    this.setState({trades: result});
                }
            )
        } else if (document.getElementById("pc").checked) {
            fetch("http://localhost:8080/trades/filter?platform=PC").then(rse => rse.json()).then(
                result => {
                    this.setState({trades: result});
                }
            )
        } else {
            alert("No filter is selected, so all trades will be displayed.")
            this.getAllTrades();
        }
    }

Both setState, and getAllTrades will throw errors here.

getAllTrades():

getAllTrades() {
        fetch("http://localhost:8080/trades/all").then(rse => rse.json()).then(
            result => {
                this.setState({trades: result});
            }
        )
    }

constructor:

constructor(props){
        super(props);

        this.state = {
            trades: []
        }
    }

didComponentMount, where getAllTrades DOES WORK:

componentDidMount() {
        this.getAllTrades();
    }

Does anyone know a solution to this problem? Thanks in advance.


Solution

  • In your getFilteredTrades and getAllTrades functions this refers to the functions itself and not the object and those functions don't have a member setState.

    You can resolve the problem in two ways:

    1. Declaring them as arrow functions which does not bind this by writing getFilteredTrades = () => { ... } and getAllTrades = () => { ... }.
    2. Bind the this keyword of the functions to the class object by writing this.getFilteredTrades = this.getFilteredTrades.bind(this) and this.getAllTrades = this.getAllTrades.bind(this) in your constructor.