Javascript Expo TaskManager-如何将更改的状态传递给外部功能?

Javascript Expo TaskManager-如何将更改的状态传递给外部功能?,javascript,reactjs,react-native,expo,background-process,Javascript,Reactjs,React Native,Expo,Background Process,我正在使用react native和expo开发一个应用程序,我很难将状态更改传递给我的任务管理器,我想知道哪里出了问题。我不确定expo task manager是否真的不能接受状态更改?基本上,当我开始我的任务时,我检查传递的状态变量是真是假,然后我想改变状态。它只工作一次,但任务管理器中的状态似乎保持不变,这意味着它一直试图将我签入,因为它仍然将提交的变量视为false: ***********APP.JS STATUS: true "****LOCATION PINGING..

我正在使用
react native
expo
开发一个应用程序,我很难将状态更改传递给我的任务管理器,我想知道哪里出了问题。我不确定expo task manager是否真的不能接受状态更改?基本上,当我开始我的任务时,我检查传递的状态变量是真是假,然后我想改变状态。它只工作一次,但任务管理器中的状态似乎保持不变,这意味着它一直试图将我签入,因为它仍然将提交的变量视为false:

***********APP.JS STATUS: true
"****LOCATION PINGING... submitted IS NOW:","false"
task.js

import * as TaskManager from 'expo-task-manager';
const TASK_FETCH_LOCATION_TEST = 'background-location-task';


export const configureBgTasks = ({ submitted, autoCheckin, autoCheckout }) => {
    
    TaskManager.defineTask(TASK_FETCH_LOCATION_TEST, ({ data, error }) => {

        if (error) {
            // Error occurred - check `error.message` for more details.
            return;
        }
        if (data) {
            //get location data from background
            const { locations } = data;
            console.log('****LOCATION PINGING... submitted IS NOW:', submitted);
            if (submitted === false) {
                autoCheckin();
                console.log('****CHECKING YOU IN...');
            } else if(submitted === true) {
                autoCheckout();
                console.log('*****CHECKING YOU OUT...')
            }
        }
    })
}
import React, { Component } from 'react';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, Button, Platform, Alert } from 'react-native';
import * as Location from "expo-location";
import { configureBgTasks } from './task';
import * as TaskManager from 'expo-task-manager';
const TASK_FETCH_LOCATION_TEST = 'background-location-task';

class App extends Component {

  state = {
    submitted: false
  }


  async componentDidMount() {
    const { status } = await Location.requestPermissionsAsync();
    if (status === 'granted') {
      console.log('location permissions are granted...')
    }
  }
  
    stopBackgroundUpdate = async () => {
      Alert.alert('TRACKING IS STOPPED');
      //Location.stopLocationUpdatesAsync(TASK_FETCH_LOCATION_TEST)
  
      //UNREGISTER TASK
      //const TASK_FETCH_LOCATION_TEST = 'background-location-task_global';
      TaskManager.unregisterTaskAsync(TASK_FETCH_LOCATION_TEST);
    }


    //REFERENCES TO STATE
    autoTrackingCheckin = () => {
      console.log('^^firing checkin')
      this.setState({ submitted: true });
    }

    autoTrackingCheckout = () => {
      console.log('^^firing checkout')
      this.setState({ submitted: false });
    }
  

    executeBackground = async () => {

      //START LOCATION TRACKING
      const startBackgroundUpdate = async () => {
        Alert.alert('TRACKING IS STARTED');
    
        if(Platform.OS==='ios') {
    
          await Location.startLocationUpdatesAsync(TASK_FETCH_LOCATION_TEST, {
            accuracy: Location.Accuracy.BestForNavigation,
            //timeInterval: 1000,
            distanceInterval: 2, // minimum change (in meters) betweens updates
            //deferredUpdatesInterval: 1000, // minimum interval (in milliseconds) between updates
            // foregroundService is how you get the task to be updated as often as would be if the app was open
            foregroundService: {
              notificationTitle: 'Using your location for TESTING',
              notificationBody: 'To turn off, go back to the app and toggle tracking.',
            },
            pausesUpdatesAutomatically: false,
          });
    
        } else {
    
          await Location.startLocationUpdatesAsync(TASK_FETCH_LOCATION_TEST, {
            accuracy: Location.Accuracy.BestForNavigation,
            timeInterval: 1000,
            //distanceInterval: 1, // minimum change (in meters) betweens updates
            //deferredUpdatesInterval: 1000, // minimum interval (in milliseconds) between updates
            // foregroundService is how you get the task to be updated as often as would be if the app was open
            foregroundService: {
              notificationTitle: 'Using your location for TESTING',
              notificationBody: 'To turn off, go back to the app and toggle tracking.',
            },
            pausesUpdatesAutomatically: false,
          });
  
        }
      }



       //WHERE THE MAGIC IS SUPPOSED TO HAPPEN
        try {

          //REFERENCES FOR VARIABLES AND FUNCTIONS
          const submitted = this.state.submitted
          const autoCheckin = this.autoTrackingCheckin
          const autoCheckout = this.autoTrackingCheckout
          
          console.log('THE VARIABLE BEING PASSED...',submitted)
          configureBgTasks({ submitted, autoCheckin, autoCheckout })
          startBackgroundUpdate();
        }
        catch (error) {
          console.log(error)
        }


    }


  


  render() {

    console.log('***********APP.JS STATUS:', this.state.submitted);

    return (
      <View style={styles.container}>
      
      <Button
          onPress={this.executeBackground}
          title="START TRACKING"
        />
        
        <Button
          onPress={this.stopBackgroundUpdate}
          title="STOP TRACKING"
        />
      <StatusBar style="auto" />
      </View>
    );
  }
}

export default App;



const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'space-evenly',
  },
});
App.js

import * as TaskManager from 'expo-task-manager';
const TASK_FETCH_LOCATION_TEST = 'background-location-task';


export const configureBgTasks = ({ submitted, autoCheckin, autoCheckout }) => {
    
    TaskManager.defineTask(TASK_FETCH_LOCATION_TEST, ({ data, error }) => {

        if (error) {
            // Error occurred - check `error.message` for more details.
            return;
        }
        if (data) {
            //get location data from background
            const { locations } = data;
            console.log('****LOCATION PINGING... submitted IS NOW:', submitted);
            if (submitted === false) {
                autoCheckin();
                console.log('****CHECKING YOU IN...');
            } else if(submitted === true) {
                autoCheckout();
                console.log('*****CHECKING YOU OUT...')
            }
        }
    })
}
import React, { Component } from 'react';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, Button, Platform, Alert } from 'react-native';
import * as Location from "expo-location";
import { configureBgTasks } from './task';
import * as TaskManager from 'expo-task-manager';
const TASK_FETCH_LOCATION_TEST = 'background-location-task';

class App extends Component {

  state = {
    submitted: false
  }


  async componentDidMount() {
    const { status } = await Location.requestPermissionsAsync();
    if (status === 'granted') {
      console.log('location permissions are granted...')
    }
  }
  
    stopBackgroundUpdate = async () => {
      Alert.alert('TRACKING IS STOPPED');
      //Location.stopLocationUpdatesAsync(TASK_FETCH_LOCATION_TEST)
  
      //UNREGISTER TASK
      //const TASK_FETCH_LOCATION_TEST = 'background-location-task_global';
      TaskManager.unregisterTaskAsync(TASK_FETCH_LOCATION_TEST);
    }


    //REFERENCES TO STATE
    autoTrackingCheckin = () => {
      console.log('^^firing checkin')
      this.setState({ submitted: true });
    }

    autoTrackingCheckout = () => {
      console.log('^^firing checkout')
      this.setState({ submitted: false });
    }
  

    executeBackground = async () => {

      //START LOCATION TRACKING
      const startBackgroundUpdate = async () => {
        Alert.alert('TRACKING IS STARTED');
    
        if(Platform.OS==='ios') {
    
          await Location.startLocationUpdatesAsync(TASK_FETCH_LOCATION_TEST, {
            accuracy: Location.Accuracy.BestForNavigation,
            //timeInterval: 1000,
            distanceInterval: 2, // minimum change (in meters) betweens updates
            //deferredUpdatesInterval: 1000, // minimum interval (in milliseconds) between updates
            // foregroundService is how you get the task to be updated as often as would be if the app was open
            foregroundService: {
              notificationTitle: 'Using your location for TESTING',
              notificationBody: 'To turn off, go back to the app and toggle tracking.',
            },
            pausesUpdatesAutomatically: false,
          });
    
        } else {
    
          await Location.startLocationUpdatesAsync(TASK_FETCH_LOCATION_TEST, {
            accuracy: Location.Accuracy.BestForNavigation,
            timeInterval: 1000,
            //distanceInterval: 1, // minimum change (in meters) betweens updates
            //deferredUpdatesInterval: 1000, // minimum interval (in milliseconds) between updates
            // foregroundService is how you get the task to be updated as often as would be if the app was open
            foregroundService: {
              notificationTitle: 'Using your location for TESTING',
              notificationBody: 'To turn off, go back to the app and toggle tracking.',
            },
            pausesUpdatesAutomatically: false,
          });
  
        }
      }



       //WHERE THE MAGIC IS SUPPOSED TO HAPPEN
        try {

          //REFERENCES FOR VARIABLES AND FUNCTIONS
          const submitted = this.state.submitted
          const autoCheckin = this.autoTrackingCheckin
          const autoCheckout = this.autoTrackingCheckout
          
          console.log('THE VARIABLE BEING PASSED...',submitted)
          configureBgTasks({ submitted, autoCheckin, autoCheckout })
          startBackgroundUpdate();
        }
        catch (error) {
          console.log(error)
        }


    }


  


  render() {

    console.log('***********APP.JS STATUS:', this.state.submitted);

    return (
      <View style={styles.container}>
      
      <Button
          onPress={this.executeBackground}
          title="START TRACKING"
        />
        
        <Button
          onPress={this.stopBackgroundUpdate}
          title="STOP TRACKING"
        />
      <StatusBar style="auto" />
      </View>
    );
  }
}

export default App;



const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'space-evenly',
  },
});
import React,{Component}来自'React';
从“博览会状态栏”导入{StatusBar};
从“react native”导入{样式表、文本、视图、按钮、平台、警报};
从“世博会地点”导入*作为地点;
从“/task”导入{configureBgTasks};
从“expo任务管理器”导入*作为任务管理器;
const TASK_FETCH_LOCATION_TEST='background LOCATION TASK';
类应用程序扩展组件{
状态={
提交:假
}
异步组件didmount(){
const{status}=wait Location.requestPermissionsAsync();
如果(状态==‘已授予’){
console.log('已授予位置权限…')
}
}
stopBackgroundUpdate=async()=>{
警报。警报(“跟踪已停止”);
//Location.stopLocationUpdatesAsync(任务提取位置测试)
//注销任务
//const TASK_FETCH_LOCATION_TEST='background-LOCATION-TASK_global';
TaskManager.unregisterTaskAsync(任务提取位置测试);
}
//对国家的提及
自动跟踪签入=()=>{
console.log(“^firing checkin”)
this.setState({submitted:true});
}
自动跟踪签出=()=>{
console.log(“^firing checkout”)
this.setState({submitted:false});
}
executeBackground=async()=>{
//开始位置跟踪
const startBackgroundUpdate=async()=>{
Alert.Alert('跟踪已启动');
if(Platform.OS==='ios'){
等待位置。startLocationUpdatesAsync(任务提取位置测试{
准确度:定位。准确度。最佳导航,
//时间间隔:1000,
距离间隔:2,//更新之间的最小变化(以米为单位)
//延迟更新间隔:1000,//更新之间的最小间隔(毫秒)
//foregroundService是让任务像应用程序打开时一样经常更新的方式
前台服务:{
notificationTitle:“使用您的位置进行测试”,
notificationBody:“若要关闭,请返回应用程序并切换跟踪。”,
},
PausesUpdateAutomatically:false,
});
}否则{
等待位置。startLocationUpdatesAsync(任务提取位置测试{
准确度:定位。准确度。最佳导航,
时间间隔:1000,
//距离间隔:1,//更新之间的最小变化(以米为单位)
//延迟更新间隔:1000,//更新之间的最小间隔(毫秒)
//foregroundService是让任务像应用程序打开时一样经常更新的方式
前台服务:{
notificationTitle:“使用您的位置进行测试”,
notificationBody:“若要关闭,请返回应用程序并切换跟踪。”,
},
PausesUpdateAutomatically:false,
});
}
}
//魔法应该发生在哪里
试一试{
//变量和函数的引用
const submitted=this.state.submitted
const autoCheckin=this.autoTrackingCheckin
const autoCheckout=this.autoTrackingCheckout
log('正在传递的变量…',已提交)
配置BGtasks({已提交,自动检查,自动检查})
startBackgroundUpdate();
}
捕获(错误){
console.log(错误)
}
}
render(){
console.log(“*********APP.JS STATUS:”,this.state.submitted);
返回(
);
}
}
导出默认应用程序;
const styles=StyleSheet.create({
容器:{
弹性:1,
背景颜色:“#fff”,
对齐项目:“居中”,
为内容辩护:“间隔均匀”,
},
});

根据世博会的文件,所有任务都需要在全球范围内的react本地代码之外定义:

它必须在JavaScript包的全局范围内调用。特别是,它不能在任何反应生命周期方法(如componentDidMount)中调用。这个限制是因为当应用程序在后台启动时,我们需要启动JavaScript应用程序,运行任务,然后关闭—在这个场景中不装载任何视图


因此,我认为最好的解决方案是使用Redux/Context来实现状态行为()

因为问题显示了相关的工作代码,所以您至少应该添加最少的相关且完整的代码片段来演示您所指的解决方案。