【问题标题】:How to run async function inside a React component's render using async await?如何使用异步等待在 React 组件的渲染中运行异步函数?
【发布时间】:2020-01-03 12:25:34
【问题描述】:

每次我的渲染运行地图循环时,我都试图运行函数getJarak()。我尝试了很多方法,但使用 async await 时仍然出现错误。

 const getJarak = async (lat, lng) => {
      const lats = this.state.lastLat;
      const lngs = this.state.lastLong;

      try {
        const response = await axios.get('https://maps.googleapis.com/maps/api/distancematrix/json?origins=' + lats + ',' + lngs + '&destinations=' + lat + ',' + lng + '&key=APIKEY');
        console.log(response.data.rows[0].elements[0].distance.text);
        const data = response.data.rows[0].elements[0].distance.text
        return data

      } catch (error) {
        console.log("error", error);
      }
    }

   return this.state.healthCareQ.map((health, id) => {
        return (
          <TouchableOpacity key={id} activeOpacity={.6} onPress={() => {
            this.props.navigation.navigate('HealthcareDisSubdis', { health });
          }}>
            <View style={stylesLocation.health} >
              <View style={{ flex: 1, borderRadius: 14 }}>
                <Image
                  style={stylesLocation.healthImage}
                  source={health.logo === "" || health.logo === null ? require('../../asset/noimage.png') : { uri: `${health.logo}` }}
                />
              </View>

              <View style={stylesLocation.healthDetails}>
                <View style={{ flex: 1, flexDirection: 'column', justifyContent: 'center' }}>
                  <Text style={{ fontSize: 14, fontWeight: 'bold', width: 230, flexWrap: 'wrap' }}>
                    {health.hfc_name}
                  </Text>
                  <Text style={{ fontSize: 12, color: '#A5A5A5', paddingTop: 5, width: 215, flexWrap: 'wrap' }}>
                    {health.address1}
                  </Text>
                </View>
              </View>
              <View style={{ flex: 0.90, justifyContent: 'center' }}>
                {/* <Text style={{ fontWeight: 'bold' }}>{parseFloat(health.distance / 1000).toFixed(1)} KM</Text> */}
                <Text style={{ fontWeight: 'bold' }}>{getJarak(health.latitude, health.longitude)}</Text>
              </View>
            </View>
          </TouchableOpacity>
        );
      })

【问题讨论】:

  • 欢迎来到 Stack Overflow。请不要上传images of code。它们不能被复制来重现问题,它们不能被未来的读者搜索,它们比文本更难阅读。请以文本形式发布实际代码以创建minimal reproducible example
  • 请检查您的值,您在代码中将对象显示为文本。
  • 这能回答你的问题吗? Reactjs async rendering of components
  • @JigarShah ,我的值 (response.data.rows[0].elements[0].distance.text) 是字符串
  • 请将错误信息的一部分以文本形式发布,以便以后的读者可以搜索到

标签: javascript reactjs react-native async-await


【解决方案1】:

通常,当获取数据有延迟时,我们需要显示某种加载图标,一旦我们获得数据,我们就会删除加载器并显示数据,这样也许你可以有一个 componentDidMount 来进行调用和设置状态和渲染函数中的数据,您可以检查数据是否存在然后显示它,否则您可以显示加载器

【讨论】:

  • 这不是对 OP 问题的回答,应该作为评论添加。
  • 谢谢下次记得@JigarShah
【解决方案2】:

getJarak 函数返回一个解析为文本的承诺。所以你不能渲染它。无论您在 Text 元素中放入什么,都必须是字符串,而不是字符串的承诺。

您应该将文本保存在组件的 state 中,并将其呈现在您的 Text 元素中,即 &lt;Text&gt;{this.state.text}&lt;/Text&gt;。然后当你运行getJarak 时,它需要用this.setState({text: newText}) 更新组件的状态,而不是像现在这样返回值。

【讨论】:

  • 就是{this.state.text}会显示不同的距离值。因为我有 25 套 lat lng。我应该将函数 getJarak 放在哪一行在渲染中运行?
  • 我认为您不希望每次重新渲染时都触发 API 调用...根据屏幕上发生的其他情况,您最终可能会触发数百或数千个一分钟次。我不确切知道这个 API 调用在做什么,但通常你会想要在 1) 用户按下按钮时触发它,2) 用户输入一些东西, 3) 如果组件刚刚挂载(即将它放在组件的componentDidMount() {...} 方法中或4) 在某个固定的预定义间隔。
  • 这应该是答案。是的,使用componentDidMount 生命周期函数。 render 生命周期函数应该是一个纯函数(没有副作用)。
  • @DrewReese ,我已经从componentDidMount内部的后端(api)获取数据,然后我想使用距离矩阵api来获取距离。
  • @SyafiqShuib 一旦你从你的 API 调用中得到响应,你就可以以任何你需要的方式操作你收到的数据。但最终您将通过将状态设置为要在屏幕上显示的文本来完成。只是为了检查您是要仅显示一个文本元素,还是要显示结果列表?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-03
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
相关资源
最近更新 更多