Skip to content

Instantly share code, notes, and snippets.

@msarsha
Last active September 9, 2021 20:41
Show Gist options
  • Save msarsha/b2904a79b8957444a4db68b11a9543d7 to your computer and use it in GitHub Desktop.
Save msarsha/b2904a79b8957444a4db68b11a9543d7 to your computer and use it in GitHub Desktop.
timers
// useTimer.tsx
function useTimer(timer: Timer) {
const { dispatch } = useContext(TimersContext);
const timeoutRef = useRef<number>();
useEffect(() => {
if (timer.done || timer.paused) {
cleanUp();
timeoutRef.current = 0;
} else {
timeoutRef.current = window.setTimeout(() => {
console.log("before dispatch", timer.elapsed);
dispatch({ type: "TICK", payload: timer.id });
console.log("after dispatch", timer.elapsed);
}, 1000);
}
return cleanUp;
}, [timer.elapsed, timer.done, timer.paused, timer.id, dispatch]);
}
// TimersContext.tsx
const reducer = (state: TimersState, action: Action): TimersState => {
switch (action.type) {
case "ADD": {
const timer: Timer = { time: action.payload, elapsed: 0, id: v1() };
return { timers: [timer, ...state.timers] };
}
case "TICK": {
const timer = state.timers.find((t) => t.id === action.payload)!;
console.log("reducer - before mutation", timer.elapsed);
timer.elapsed = timer.elapsed + 1;
timer.done = timer.elapsed === timer.time;
console.log("reducer - after mutation", timer.elapsed);
return { timers: [...state.timers] };
}
default:
return state;
}
};
const TimersContextProvider: FunctionComponent = ({ children }) => {
const [state, dispatch] = useReducer(reducer, { timers: [] });
const contextValue = useMemo(() => ({ state, dispatch }), [state, dispatch]);
return (
<TimersContext.Provider value={contextValue}>
{children}
</TimersContext.Provider>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment