简体   繁体   中英

React TypeError: this.setState is not a function

currently I'm writing an app in react that works with .NET Core web api and I'm getting:

TypeError: this.setState is not a function

I will explain when I get this error exactly in last paragraph

Now the view is intended to work as follows, on a page I have a table with data seeded from an array of JSON data and couple of inputs next to it. When I click on a table row it will put row data into inputs and I can edit the data from here. Two functions are handling this, first: editData is sending POST request to api and then it modify edited object in database. After this request is done second function: getData shall run and refresh a table with new, edited data. Here is how it looks:

Constructor:

class SomeClass extends React.Component {
    constructor(props) {
        super(props);
        this.props = props;
        this.state = {
            someArray: [],
            tableData1: "",
            tableData2: "",

            validationSummary: [],
            isSubmitting: false
        }
        this.handleChange = this.handleChange.bind(this); //function to handle change on inputs
        this.getData = this.getData.bind(this);
        this.editData= this.editData.bind(this);
    }

Function for getting data:

    async getData() {
        return fetch("http://localhost:5000/api/somecontroller/getroute")
            .then(response => response.json())
            .then(data => {
                this.setState({
                    someArray: data,
                    tableData1: "",
                    tableData2: "", //clear inputs
                })
            })
    }

And finally edit object function:

    async editData() {
        var validationSummary = []

        if (this.state.tableData1 !== "" && this.state.tableData2 !== "") {
            this.setState = {
                validationSummary: [], //clear summary
                isSubmitting: true
            }

            let response = await fetch('http://localhost:5000/api/somecontroller/editroute', {
                method: "POST",
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    data1: tableData1,
                    data2: tableData2
                })
            });

            if (response.status !== 200) {
                validationSummary.push("Something went wrong")
                this.setState = {
                    validationSummary: validationSummary,
                    isSubmitting: false
                }
            }

            else {
                await this.getData()
            }
        }

        else {
            validationSummary.push("Inputs cannot be empty")
            this.setState = {
                validationSummary: validationSummary,
                isSubmitting: false
            }
        }
    }

The problem is that whenever I edit some data and submit it to send request to API, website stops and I get the before mentioned error on this.setState line in the getData function:

    async getData() {
        return fetch("http://localhost:5000/api/somecontroller/getroute")
            .then(response => response.json())
            .then(data => {
                this.setState({ //getting error here

I've read couple other questions similiar to this but everytime the solution was to bind function to this in constructor . However as you can see in my code I have binded both getData and editData functions to this . I probably have to mention that when I REMOVE all this.setState references from editData function, page is working properly and I'm no longer getting any error. I'm pretty new to react so I'm curious as to why I'm getting this error as it is and how can I fix this without removing this.setState references from editData function, because I need them for displaying error messages.

UPDATE

amrs-tech's answer fixed my problem, in editData changing this.setState = {...} to this.setState({...}) made it work. Hope it will be useful for someone in future!

if (this.setState.tableData1 !== "" && this.setState.tableData2 !== "")

this is incorrect. It should be like:

if (this.state.tableData1 !== "" && this.state.tableData2 !== "")

Your editData should be like:

async editData() {
        var validationSummary = []

        if (this.state.tableData1 !== "" && this.state.tableData2 !== "") {
            this.setState ({
                validationSummary: [], //clear summary
                isSubmitting: true
            })

            let response = await fetch('http://localhost:5000/api/somecontroller/editroute', {
                method: "POST",
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    data1: tableData1,
                    data2: tableData2
                })
            });

            if (response.status !== 200) {
                validationSummary.push("Something went wrong")
                this.setState ({
                    validationSummary: validationSummary,
                    isSubmitting: false
                })
            }

            else {
                await this.getData()
            }
        }

        else {
            validationSummary.push("Inputs cannot be empty")
            this.setState ({
                validationSummary: validationSummary,
                isSubmitting: false
            })
        }
    }

Hope it works. You can refer for some details about React state and lifecycle - here

setState is a function , also state and props are immutable .

// this.state.tableData1
this.setState.tableData1

// this.setState({...})
// and either way its should considered immutable
this.setState = {
  validationSummary: [], //clear summary
  isSubmitting: true
};

// also this is redundant because props are immutable.
this.props = props;

another quick way to fix this problem is to keep 'this' as variable

async getData() {
var scope = this;
        return fetch("http://localhost:5000/api/somecontroller/getroute")
            .then(response => response.json())
            .then(data => {
                scope.setState({ // scope replace 'this' here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM