首页 > 解决方案 > Expo - 如何根据 TaskManager 的输出更新状态

问题描述

我将不胜感激您对此主题的任何指导,在此先感谢您。

这是我的情况:我已经设置了 TaskManager 来跟踪它正在运行的设备的位置,效果很好。我正在苦苦挣扎的地方是将 TaskManager 返回的数据作为状态返回到我的 App 组件中。

这是我的问题的简化示例:

class App extends Component {
  state = {}
  // 'this' does not exist within a static method.
  static updateState = (data) => this.setState(data)
  render = () => { return <div>...</div> }
}
​
TaskManager.defineTask(LOCATION_TASK_NAME, ({ data, error }) => {
  const { locations } = data // How can I get locations into state?
  App.updateState(locations) // Won't work as I can't use 'this' within a static method!
})

实际文件如下所示:

import React from 'react'
import { StyleSheet, Text, View } from 'react-native'
import * as Location from 'expo-location'
import * as TaskManager from 'expo-task-manager'
import * as Permissions from 'expo-permissions'

const LOCATION_TASK_NAME = 'background-location-task'

export default class App extends React.Component {
  state = {
    latitude: 0,
    longitude: 0,
  }

  static updateState(latitude, longitude) {
    // updateState receives the data correctly, I just can't 
    // work out how to update the component state with values.
    console.log(latitude, longitude) 
    // this.setState({ latitude, longitude }) // Doesn't work
  }

  notStaticUpdateState(latitude, longitude) {
    // console.log(latitude, longitude) // won't work
  }

  async componentDidMount() {
    const { status } = await Permissions.askAsync(
      Permissions.LOCATION,
      Permissions.USER_FACING_NOTIFICATIONS,
    )

    if (status === 'granted') {
      await Location.startLocationUpdatesAsync(
        LOCATION_TASK_NAME,
        {
          accuracy: Location.Accuracy.Highest,
          distanceInterval: 1,
          timeInterval: 1000,
        },
      )
    }
  }

  render() {
    const { latitude, longitude } = this.state
    return (
      <View style={styles.container}>
        <Text>Lat: {latitude}</Text>
        <Text>Lng: {longitude}</Text>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    flex: 1,
    justifyContent: 'center',
  },
})

TaskManager.defineTask(LOCATION_TASK_NAME, ({ data, error }) => {
  if (error) {
    return
  }
  if (data) {
    const { latitude, longitude } = data.locations[0].coords
    App.updateState(latitude, longitude)
    // App.notStaticUpdateState(latitude, longitude) // won't work
  }
})

标签: javascriptreactjsreact-nativeexpo

解决方案


推荐阅读