import React, { useState, useEffect, useRef } from 'react' import { FiPlay, FiPause, FiSquare } from 'react-icons/fi' function safeCall(fn) { typeof fn === 'function' && fn() } export const Player = ({ onTick, onStart, onStop, onPause, delay }) => { const [isRunning, start, stop] = usePlayer(stop => onTick(stop), delay) const handleStart = () => { safeCall(onStart) start() console.log('yay') } const handleStop = () => { safeCall(onStop) stop() } const handlePause = () => { safeCall(onPause) stop() } return (
{isRunning && ( )} {!isRunning && ( )}
) } function usePlayer(onTick, delay) { const [isRunning, setRunning] = useState(false) const start = () => setRunning(true) const stop = () => setRunning(false) useInterval(() => onTick(stop), isRunning ? delay : null) return [isRunning, start, stop] } // from: https://overreacted.io/making-setinterval-declarative-with-react-hooks/ function useInterval(callback, delay) { const savedCallback = useRef() // Remember the latest callback. useEffect(() => { savedCallback.current = callback }, [callback]) // Set up the interval. useEffect(() => { function tick() { savedCallback.current() } if (delay !== null) { let id = setInterval(tick, delay) return () => clearInterval(id) } }, [delay]) }