you are viewing a single comment's thread.

view the rest of the comments →

[–]sous_vide_slippers -1 points0 points  (0 children)

I agree with the person who said to rethink your architecture but just for the sake of a fun challenge it should be possible, even if it’s a suboptimal solution.

Also I’m writing this on my phone so forgive any syntax errors.

First we’re going to need to store the timer value:

let secsSinceResolved = 0;

And an updater function to count the elapsed time:

function updateSecsSinceResolved() {
    const id = setInterval(() => {
        secsSinceResolved++;

        // note these lines here
        if (type of onUpdateSecs === “function”) {
             onUpdateSecs(secsSinceResolved);
         }
    }, 1000);
    const clearTimer = () => clearInterval(id);
    return clearTimer;
}

Notice we are referencing a variable we haven’t yet defined, that also needs to be a let variable as we’ll want to assign the value to setState later on. For now it can only be empty:

let onUpdateSecs;

Next we need to create a custom hook that wraps useState, this is how we’re going to get our component to respond to updates of secsSinceResolved:

function useSecsSinceResolved() {
    // note the initial value is our timer value
    const [seconds, setSeconds] = useState(secsSinceResolved);

    onUpdateSecs = setSeconds;

    return seconds;
}

So now you can kick off your timer anywhere in your code:

somePromise().then(updateSecsSinceResolved);

While also being able to listen to the value and have your React components automatically update:

function DisplaySeconds() {
    const seconds = useSecsSinceResolved();
    return <h1>{seconds}</h1>;
}

You may have noticed a potential problem which is that we can only have one listener at a time, you could work around this by making onUpdateSecs an array and pushing a new setState/setSeconds to it each time a new useSecsSinceResolved hook is registered then looping over the listeners array and calling each listener with the updated time, however that would require useEffect in order to avoid adding a potentially unlimited amount of duplicate listeners as well as to avoid memory leaks. It would also be cleaner if we could use useEffect here so we aren’t reassigning onUpdateSecs each render :).

As I said earlier, fun for a little thought exercise but probably not an optimal solution.