【问题标题】:Trying to store object into AsyncStorage but it stores empty values试图将对象存储到 AsyncStorage 但它存储空值
【发布时间】:2022-01-21 07:26:06
【问题描述】:

我正在使用 react-native 开发一个正在运行的跟踪器应用程序。我每 5 米获取用户的位置,然后将他们的纬度和经度存储在路线数组中。当用户结束运行时,我想将数组与 AsyncStorage 中的所有点一起存储。问题是当它存储一个空数组时。

这是它存储的内容。我不确定为什么。任何帮助表示赞赏。

Object {
  "route": Array [],
  "speed": 0,
  "totalDistance": 0,
}

我的代码

完整项目的github链接。 https://github.com/jasingh784/runningTrackerv2

import React, {useState, useEffect} from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import * as Location from 'expo-location';
import { getDistance } from '../utils';
import Timer from './Timer';
import { storeRun } from '../utils';


export default function NewRun() {
  const [route, setRoute] = useState([]);
  const [errorMsg, setErrorMsg] = useState(null);
  const [speed, setSpeed] = useState(0);
  const [totalDistance, setTotalDistance] = useState(0);


  //setup watch position
  useEffect(() => {
    (async () => {
      let { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        setErrorMsg('Permission to access location was denied');
        return;
      }

      locationSubscription = await Location.watchPositionAsync({accuracy: Location.Accuracy.BestForNavigation, distanceInterval: 5}, locationUpdated);
    })();

    return () => {
      endRun()
      locationSubscription.remove();
    }

  }, []);

  //this effect runs every time a new coord is added to the route array.
  //it calls a function to calculate the distance between two points. it then adds the 
  //result to the total distance. 
  useEffect(() => {
    if(route.length >= 2) {
      distBetweenLastPoints = getDistance(route[route.length - 1]["latitude"], 
                  route[route.length - 2]["latitude"],
                  route[route.length - 1]["longitude"],
                  route[route.length - 2]["longitude"] );
        
      setTotalDistance(totalDistance => totalDistance + distBetweenLastPoints)
    }
    return ()=> {
      //not sure if there is any clean up in this effect. i dont think so.
      
    }
  }, [route])


  //get location and add entry into the route array. This array contains points
  //that can be used to map out the route.
  const locationUpdated = (locObject) => {
    console.log('inside locationupdated')
    //console.log(locObject)

    setRoute(oldRoute => [...oldRoute, {
      latitude: locObject.coords.latitude,
      longitude: locObject.coords.longitude,
    }]);

    setSpeed(locObject.coords.speed);

  }

  //this function is called when user presses End Run.
  //it puts all the data for the run into one object and 
  //then stores it in local storage. it only stores the last run
  //also remves the location subscription so we app can stop tracking 
  //location
  const endRun = () => {
    const run = {route, totalDistance, speed}
    console.log(run)
    storeRun(run);
    locationSubscription.remove();
  }


  let text = 'Waiting..';
  if (errorMsg) {
    text = errorMsg;
  } else if (route) {
    text = JSON.stringify(route);
  }

  return (
    <View style={styles.container}>
      <Text style={styles.paragraph}>{Math.round((speed * 2.2369) * 100) / 100} mph</Text>
      <Text>Distance Travelled: {route ? totalDistance : 0} miles</Text>
      <Timer />
      <Button title="End Run" onPress={endRun}/>
    </View>
  );
}

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

要存储运行的代码

export const storeRun = async (runData) => {
        try {
          const jsonValue = JSON.stringify(runData)
          await AsyncStorage.setItem('previousRun', jsonValue)
        } catch (e) {
          // saving error
          console.log(e);
        }
        console.log('added previous run to local storage');
      }

【问题讨论】:

    标签: javascript arrays reactjs react-native asyncstorage


    【解决方案1】:

    您可以尝试React.useRef参考经纬度的更新值。

    因为当您注册 pubsub 监听器时,状态值始终在事件回调中固定。

    下面的代码是使用useRef 获取事件回调或发布订阅中状态的最新更新值的简单示例。

    const [counter, setCounter] = React.useState(0); // this is the target
    
    const counterRef = React.useRef(); // ref
    counterRef.current = counter; // ref always refers to counter
    
    
    // event callback
    const func = () => {
      // This should NOT be "counter" itself. Should be "counterRef"
      console.log(counterRef.current);
    };
    
    
    // event listener or pubsub
    React.useEffect(() => {
      window.addEventListener("click", func);
    }, []);
    
    return (
      <button onClick={() => setCounter(counter + 1)}>
        click me!
      </button>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-27
      • 2020-03-25
      • 2019-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多