试图将对象存储到 AsyncStorage 但它存储空值
Trying to store object into AsyncStorage but it stores empty values
我正在使用 react-native 开发 运行ning 跟踪器应用程序。我每 5 米获取一次用户的位置,然后将他们的纬度和经度存储在路线数组中。当用户结束 运行 时,我想将包含所有点的数组存储在 AsyncStorage 中。问题是当它存储一个空数组时。
这是它存储的内容。我不确定为什么。感谢任何帮助。
Object {
"route": Array [],
"speed": 0,
"totalDistance": 0,
}
我的代码
github link 完整项目。 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',
},
});
storeRun 代码
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');
}
您可以尝试React.useRef
参考纬度和经度的更新值。
因为当您注册 pubsub 侦听器时,状态值始终固定在事件回调中。
下面的代码是一个简单的示例,使用 useRef
获取事件回调或 pubsub 中状态的最新更新值。
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>
好的。所以我找到了解决问题的方法。我创建了一个新功能,并将用于存储项目的代码放入其中。然后我制作了一个按钮并在按下按钮时调用该函数。我不确定为什么相同的代码在清理我的 useffect 挂钩时不起作用。可能是我的组件在代码完成到 运行 之前被卸载了???我对反应还不够了解。
我正在使用 react-native 开发 运行ning 跟踪器应用程序。我每 5 米获取一次用户的位置,然后将他们的纬度和经度存储在路线数组中。当用户结束 运行 时,我想将包含所有点的数组存储在 AsyncStorage 中。问题是当它存储一个空数组时。
这是它存储的内容。我不确定为什么。感谢任何帮助。
Object {
"route": Array [],
"speed": 0,
"totalDistance": 0,
}
我的代码
github link 完整项目。 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',
},
});
storeRun 代码
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');
}
您可以尝试React.useRef
参考纬度和经度的更新值。
因为当您注册 pubsub 侦听器时,状态值始终固定在事件回调中。
下面的代码是一个简单的示例,使用 useRef
获取事件回调或 pubsub 中状态的最新更新值。
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>
好的。所以我找到了解决问题的方法。我创建了一个新功能,并将用于存储项目的代码放入其中。然后我制作了一个按钮并在按下按钮时调用该函数。我不确定为什么相同的代码在清理我的 useffect 挂钩时不起作用。可能是我的组件在代码完成到 运行 之前被卸载了???我对反应还不够了解。