首页 > 解决方案 > Set State from ajax call to insert into db outside function?

问题描述

    async componentDidMount(){
        // Metrics
        await this.forumMetrics();
    }

I'm trying to insert data from an API that I'm calling from my ajax call. However, when I try to set state inside the function, it tells me that setstate is not a function. I looked this up and a lot of posts told me I had to .bind(this) which I did but it's still giving me the error.

Futhermore, I also ran into another problem of not being able to access the state from outside the function cause I need to insert it into my service worker that inserts the data into my db. I have access within the function but not outside which I need in order to bind the state to my model in my back-end.

Any suggestions? I feel like I'm close but missing something.

Here is my code:

async forumMetrics(data){
    const getuserData = () => {
        $.getJSON({
            type: 'GET',
            url: 'https://json.geoiplookup.io/api?callback=?',
            success: (data) => {
                //console.log(data);
                this.setState({
                    userIp: data.ip,
                    userCity: data.city,
                    userRegion: data.region,
                    userCountry: data.country_name,
                    userLatitude: data.latitude,
                    userLongitude: data.longitude
                })
                //console.log(this.state);
            },
        })
    }

    const result = getuserData();

    result;

    const metricData = {
        userIp: this.state.userIp,
        userCity: this.state.userCity,
        userCountry: this.state.userCountry,
        userRegion: this.state.userRegion,
        userLatitude: this.state.userLatitude,
        userLongitude: this.state.userLongitude,
        vieweddateTime: Moment().format('YYYY-MM-DD hh:mm:ss'),
        createdDate: Moment().format('YYYY-MM-DD hh:mm:ss'),
        year: Moment().format('YYYY'),
        month: Moment().format('MM')
    }

    const metricForum = await MetricService.insertpageView(metricData);

}

标签: reactjs

解决方案


您真的不应该使用 jQuery 来检索数据。使用fetch()oraxios或类似的东西。

话虽如此,您的问题可以通过使用箭头函数来解决。而不是function getuserData...,试试这个:

    const getuserData = (result) => {
        $.getJSON({
            type: 'GET',
            url: 'https://json.geoiplookup.io/api?callback=?',
            success: (data) => {
                console.log(data);
                // I have access to data in this function
                this.setState({
                    userIp: data.ip
                })
            },
        })
    }

请注意,this箭头函数中的 绑定到父函数的this.

另外,请记住将您的forumMetrics函数绑定到组件构造函数上。

编辑:

我没看到你getuserData()在任何地方打电话...

编辑2:

您可能希望像这样创建getUserData一个单独的函数:

async forumMetrics(data){
    const data = await this.getuserData();
    console.log(data);

    this.setState({
                userIp: data.ip,
                userCity: data.city,
                userRegion: data.region,
                userCountry: data.country_name,
                userLatitude: data.latitude,
                userLongitude: data.longitude
    });
}

getUserData(data) {
  return new Promise((accept, reject) => {
    $.getJSON({
      type: 'GET',
      url: 'https://json.geoiplookup.io/api?callback=?',
      success: accept,
    }) 
  });
}

请注意,函数await内的关键字async将等待 promise 完成并使用接受的值继续执行。

您可以通过使用来进一步简化getUserData功能fetch

getUserData() {
  return fetch('https://json.geoiplookup.io/api?callback=?');
}

推荐阅读