Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

307
Vistas
Reaccionar, reloj de velocidad variable con setTimeout

objetivo: crear un componente Clock que llame a un método de devolución de llamada a intervalos regulares, pero cuya velocidad se pueda controlar.

Parte difícil: no reinicie el temporizador del reloj inmediatamente cuando cambie la velocidad, pero en el siguiente "tick" verifique la velocidad deseada y, si tiene cambios, reinicie el intervalo actual y programe uno nuevo. Esto es necesario para mantener el reloj a un ritmo suave al cambiar la velocidad.

Pensé que pasar una función getDelay que devuelve el retraso (en lugar del valor del retraso en sí) haría que esto funcionara, pero no es así.

Si dejo que useEffect rastree la función getDelay , se restablecerá cuando cambie el retraso. Si no realiza un seguimiento getDelay , la velocidad no cambiará mientras el reloj esté funcionando.

 import React, { useEffect, useRef } from "react"; type Callback = () => void; function useInterval(tickCallback: Callback, getDelay: () => number, isPlaying: boolean) { const refDelay = useRef<number>(getDelay()); useEffect(() => { let id: number; console.log(`run useEffects`); function tick() { const newDelay = getDelay(); if (tickCallback) { console.log(`newDelay: ${newDelay}`); tickCallback(); if (newDelay !== refDelay.current) { // if delay has changed, clear and schedule new interval console.log(`delay changed. was ${refDelay.current} now is ${newDelay}`) refDelay.current = newDelay; clear(); playAndSchedule(newDelay); } } } /** clear interval, if any */ function clear() { if (id) { console.log(`clear ${id}`) clearInterval(id); } } /** schedule interval and return cleanup function */ function playAndSchedule(delay: number) { if (isPlaying) { id = window.setInterval(tick, delay); console.log(`schedule delay id ${id}. ms ${delay}`) return clear } } return playAndSchedule(refDelay.current); }, // with getDelay here the clock is reset as soon as the delay value changes [isPlaying, getDelay]); } type ClockProps = { /** true if playing */ isPlaying: boolean; /** return the current notes per minute */ getNpm: () => number; /** function to be executed every tick */ callback: () => void; } export function Clock(props: ClockProps) { const { isPlaying, getNpm, callback } = props; useInterval( callback, () => { console.log(`compute delay for npm ${getNpm()}`); return 60_000 / getNpm(); }, isPlaying); return (<React.Fragment />); }
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

puedes usar algo como esto:

 import React, { useCallback, useEffect, useMemo, useRef } from 'react'; function useInterval(tickCallback: () => void, delay: number, isPlaying: boolean) { const timeout = useRef<any>(null); const savedDelay = useRef(delay); const savedTickCallback = useRef(tickCallback); useEffect(() => { savedDelay.current = delay; }, [delay]) useEffect(() => { savedTickCallback.current = tickCallback; }, [tickCallback]) const startTimeout = useCallback(() => { const delay = savedDelay.current; console.log('next delay', delay); timeout.current = setTimeout(() => { console.log('delay done', delay); savedTickCallback.current(); startTimeout(); }, savedDelay.current); }, []); useEffect(() => { if (isPlaying) { if (!timeout.current) { startTimeout(); } } else { if (timeout.current) { clearTimeout(timeout.current); } } }, [isPlaying, startTimeout], ); } type ClockProps = { /** true if playing */ isPlaying: boolean; /** return the current notes per minute */ getNpm: () => number; /** function to be executed every tick */ callback: () => void; } export const Clock: React.FC<ClockProps> = ({ isPlaying, getNpm, callback }) => { const delay = useMemo(() => { console.log(`compute delay for npm ${getNpm()}`); return 60_000 / getNpm(); }, [getNpm]); useInterval(callback, delay, isPlaying); return null; };
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda