反应-无法在Promise中设置setState

时间:2019-05-31 18:10:32

标签: javascript reactjs promise

我试图在Promise的then()内设置状态,但是状态值未保存,并且无法在then()之外访问。

下面是更新代码:

handleSelect = location => {
  this.setState({ location });
  geocodeByAddress(
    location
  )
  .then(results => getLatLng(results[0]))
  .then(latLng => {
    this.setState({
      location_latitude: latLng.lat,
      location_longitude: latLng.lng,
    })
    console.log(this.state.location_latitude); // returns the correct value
  })
  console.log(this.state.location_latitude); // returns null (the originally declared value)
}

如果我console.log(this.state.location_latitude),我得到一个null值。但是,如果我在then()块中使用console.log,我将获得正确的值。在这种情况下如何设置状态?

已更新说明:

为了在此处提供整个逻辑的更好的上下文:我使用的是Google地方信息自动填充组件,该组件允许用户从下拉菜单中选择位置。当用户从下拉列表中选择位置时,将调用上述方法handleSelect。然后,我使用geocodeByAddress方法提取用户选择的地点的纬度和经度,这是一个承诺。然后,我需要检索纬度和经度并相应地设置状态,然后将其用于发送到数据库。我还无法将值提交到数据库,因为用户还需要填写其他表单输入(这些输入也存储在状态中),一旦他单击“提交”,我将在表单中提交所有状态元素。单一调用后端。因此,我没有要使用componentDidMount()更新的东西,或者没有任何更新要使用componentDidUpdate()。无论如何,我只能将状态值存储在geocodeByAddress的then内(如果我在这里错了,请更正我)。因此,我必须能够在then块内修改状态值。

3 个答案:

答案 0 :(得分:1)

问题是,当您set-state之后,您看不到状态结果。这就是console.log返回null的原因。确保您的console.logrender block中。这是因为set-state个动作是asynchronous,并且为了提高性能而进行了批量处理。在setState的文档中对此进行了说明。 看看这个=> Why is setState in reactjs Async instead of Sync?

答案 1 :(得分:0)

您需要将函数上下文绑定到当前的类/组件。尝试以下类似的方法。创建一个类似“ callSetState”的函数与此绑定,并在调用时将值作为参数传递给它。

import React, { Component } from 'react';
class Test extends Component{
    constructor() {
        super()
        this.callSetState = this.callSetState.bind(this);
    }

    callSetState(latitude, longitude) { 
        this.setState({
            location_latitude: latitude,
            location_longitude: longitude,
        })
    }

/* Call this func in your class and call callSetState which is already bound to your component in constructor */

    // geocodeByAddress(location)
    //     .then(results => getLatLng(results[0]))
    //     .then(latLng => this.callSetState(latLng.lat, latLng.lng));

}

答案 2 :(得分:-1)

这显然是您的数据通话无法响应的问题。

您的反应代码看起来不错,但我建议随地吐出代码。

1)service.js文件-这将执行查询并返回数据或返回错误。

2)位置组件componentDidMount()或useEffect(()=> {},[])获取数据并更新state / useState()

要给您一个代码段,我需要您提供latLangresults的控制台日志。

非常感谢