Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

174
Visualizações
Aumentar un valor de forma no lineal al mantener presionado un botón (Reaccionar)

Pido disculpas si esto se ha preguntado antes, pero todavía no he encontrado nada que me ayude, ¡y soy nuevo en React!

Quiero un valor para aumentar cada n número de segundos que el usuario mantiene presionado un botón. ¡En este momento está aumentando linealmente cada 35 milisegundos!

Hasta ahora tengo algo como esto:

 function Increaser() { const [value, setValue] = useState(0); const changeTimer: React.MutableRefObject<any> = useRef(null); function timeoutClearUp() { clearInterval(changeTimer.current); } function increment() { changeTimer.current = setInterval(() => setValue(prev => prev + 1), 35); }; function onChange(e: any) { setValue(parseInt(e.target.value)); } return ( <div> <button onMouseUp={timeoutClearUp} onMouseDown={increment}>INCREASE</button> <input type="number" value={value} onChange={(e) => {onChange(e)}} /> </div> ); }

¡He intentado agregar otra ref pero no parece funcionar! ¿Qué es una pequeña cosa que puedo agregar a este código para garantizar que cada segundo value se incremente en un valor cada vez mayor (cuanto más tiempo mantenga presionado el botón el usuario).

¡Muchas gracias!

  • Reaccionar: ^17.0.2
  • Texto mecanografiado: ^4.5.5
about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Debido a que nadie le dio una solución real, aquí hay una forma de hacer lo que quiere.
Lo que he hecho aquí es usar una referencia a la entrada y actualizar el valor en su estado una vez que dejan de hacer clic en el botón de incremento o cuando cambian la entrada manualmente.
En la función de incremento, uso setTimeout para crear un intervalo personalizado, y este intervalo usa una ecuación matemática para determinar cuál será el próximo tiempo de espera/intervalo. La ecuación que utilicé pasará de 35 ms (inicio) a 10 ms (final) en 41 segundos y no bajará de 10 ms.
Aquí hay un gráfico de tiempo de lo que uso en este ejemplo para acelerar el intervalo. (el eje x es el tiempo en segundos y el eje y es el retraso en milisegundos) Gráfico de la función de tiempo que usé.

 import { useState, useRef } from 'react'; function Increaser() { const [value, setValue] = useState(0); const myInputRef = useRef<HTMLInputElement>(null); let myTimeout: ReturnType<typeof setTimeout>; let startTime: Date; function stopInterval() { clearTimeout(myTimeout!);//Stop the interval in essence setValue(parseInt(myInputRef.current!.value!)||0) //Set the value of the input (in the mean time value is "floating") } function increment() { startTime = new Date();//Initialize when we started increasing the button myTimeout = setTimeout(function runIncrement() {//Start the timeout which is really a controlled interval const val = (parseInt(myInputRef!.current!.value)||0)+1;//Increment the value of the ref's target myInputRef!.current!.value = (val).toString()//Assign that incremented value to the ref const now = new Date(); const delta = now.getTime() - startTime.getTime(); const n = 10 + (1/(Math.pow(1.1,delta/1000-(2*Math.log(5))/Math.log(1.1))));//Whatever //The math function I have chosen above will go from 35 ms to 10 ms in 41 seconds. //The function will not go lower than 10 ms and starts at 35 ms //However you can use whatever function or math you want to get it to do as you wish. //... //whatever logic here you want to calculate when we will trigger the increment again. //... myTimeout = setTimeout(runIncrement, parseInt(n.toString()));//Increment again after the variable n milliseconds which we calculate above },35);//Start the interval with an initial time of 35 milliseconds //Now we know when the interval started, and we can }; function onChange(e: any) { setValue(parseInt(e.target.value)); } return ( <div> <button onMouseUp={stopInterval} onMouseDown={increment}>INCREASE</button> <input type="number" onChange={(e) => {onChange(e)}} ref={myInputRef} /> </div> ); } export default Increaser;

`

Me disculpo por el ligero formato que SO está haciendo aquí (en combinación con mi editor de código VS).

about 4 years ago · Juan Pablo Isaza Relatório

0

Gracias a la respuesta de SharpInnovativeTechnologies, me di cuenta de lo tonto que era y encontré una solución fácil:

 function increment() { const past = Date.now() const rate = 500; changeTimer.current = setInterval(() => { const diff = Math.floor((Date.now() - past) / rate); setValue(prev => prev + (1 + diff)) }, 50); }

Donde rate es una especie de ajuste de sensibilidad.

Entonces, cada 50 ms, The Date.now() - past aumenta y aumenta el value con el setter.

about 4 years ago · Juan Pablo Isaza Relatório

0

Si quieres crecer cada segundo, debes cambiar

 ... changeTimer.current = setInterval(() => setValue(prev => prev + 1), 35); ... <input type="number" value={value} />

a

 ... changeTimer.current = setInterval(() => setValue(prev => prev + 35), 35); ... <input type="number" value={value/1000} />

porque el segundo parámetro de setInterval es milisegundos.

Código completo y demostración:

Editar selección de TextFieldStart

 import React, { useState, useRef } from "react"; export default function Increaser() { const [value, setValue] = useState(0); const changeTimer = useRef(null); function timeoutClearUp() { if (changeTimer.current) { clearInterval(changeTimer.current); changeTimer.current = null; } } function increment() { changeTimer.current = setInterval(() => { setValue((prev) => prev + 35); }, 35); } return ( <div> <button onMouseUp={timeoutClearUp} onMouseDown={increment}> INCREASE </button> <button onClick={() => { setValue(0); }} > Reset </button> <div>{value / 1000}</div> </div> ); }
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda