'PWA with React: Trying to create a object that updates every second and is accessible for many components
I'm currently working on a PWA build with React.
I'm looking for a way to create one object which contains information like the current time (incl. seconds), current date, the users location, the users speed. These information must update exactly every second. Also the infos must be shown on the screen and therefore the screen needs to re-render every time one of the infos changes. Additionally I want to access these infos from different components. (that's why I was trying to use reacts useContext)
If have tried many different approaches using useState, useEffect, useContext, setIntervall, setTimeout etc. but nothing works completely.
Either the values are not updated regularly or I get into an infinite loop in which new intervals are created over and over again and the performance drops.
If you now what my problem is or have an idea on how to implement this it would be great!
Thanks in advance!
Here is my current version:
import { createContext, useEffect, useState } from "react";
//just initializing the context with some dummy values
const DrivingContext = createContext({
currentDate: "01.01.2022",
currentTime: "00:00:00",
currentSpeed: "0 km/h",
currentLatLng: { lat: 50, lng: 6 },
currentAddress: "City",
});
export function DrivingContextProvider(props) {
//creating a state object so that the components will re-render
//(don't know if that's necessary)
const [infos, setInfos] = useState({
date: DrivingContext.currentDate,
time: DrivingContext.currentTime,
speed: DrivingContext.currentSpeed,
latLng: DrivingContext.currentLatLng,
address: DrivingContext.currentAddress,
});
useEffect(() => {
setInterval(updateValues, 1000);
}, []);
function updateValues() {
var currentDate = new Date();
const timeStr = currentDate.toTimeString().slice(0, 8);
const dateStr = currentDate.toLocaleDateString();
var speed = infos.speed;
var latLngObj = infos.latLng;
var addressObj = infos.address;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
if (position.coords.speed !== null) {
speed = position.coords.speed;
}
latLngObj = {
lat: position.coords.latitude,
lng: position.coords.longitude,
};
var link =
"https://api.geoapify.com/v1/geocode/reverse?lat=" +
position.coords.latitude +
"&lon=" +
position.coords.longitude
"&apiKey=MYKEY";
var requestOptions = {
method: "GET",
};
fetch(link, requestOptions)
.then((response) => response.json())
.then((data) => {
var addressStr =
data.features[0].properties.address_line1 +
", " +
data.features[0].properties.postcode +
" " +
data.features[0].properties.city;
addressObj = addressStr;
});
});
}
setInfos({
date: dateStr,
time: timeStr,
speed: speed,
latLng: latLngObj,
address: addressObj,
fetched: true,
});
}
const context = {
currentDate: infos.date,
currentTime: infos.time,
currentSpeed: infos.speed,
currentLatLng: infos.latLng,
currentAddress: infos.address,
alreadyFetched: infos.fetched,
};
return (
<DrivingContext.Provider value={context}>
{props.children}
</DrivingContext.Provider>
);
}
export default DrivingContext;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|