Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

228
Views
¿Por qué el valor de referencia se incrementa dos veces?

Tengo este código aquí:

 export default function App() { const [count, setCount] = useState(0); const [step, setStep] = useState(0); const reff = useRef(0); useEffect(() => { const id = setInterval(() => { setCount((c) => { console.log({ step }, "reff.current before incr ", reff.current); reff.current = reff.current + step; console.log("ref.curret after incr ", reff.current); return c + step; }); }, 6000); return () => clearInterval(id); }, [step]); return ( <> <h1>Count:{count}</h1> <h1>Step: {step}</h1> <input type="button" onClick={(e) => setStep((prevStep) =>(prevStep + 1))} value="+ step" /> </> ); }

Puede verlo aquí: https://codesandbox.io/s/gracious-roentgen-31ntb?file=/src/App.js:0-817

Tenga en cuenta que estoy incrementando la referencia dentro de la devolución de llamada setCount

Cuando el componente se carga, se inicia un setInterval. Si vuelvo a activar useEffect incrementando el paso antes de que pasen 6 segundos , borra setInterval y crea uno nuevo.

Y ahora, si no incremento el paso nuevamente y espero 6 segundos, veo step: 1 reff.current before incr, 0 por primera vez que se llama la devolución de llamada setInterval.

Después de incrementar en la siguiente línea ( reff.current = reff.current + step ), veo "ref.curret after incr ", 1

Cuando se vuelve a llamar a la devolución de llamada setInterval después de 6 segundos, veo

step: 1 reff.current before incr, 2 //how did this become 2

No entiendo cómo el valor de reff.current es 2.

Esto solo sucede cuando incremento el paso (que borra el primer intervalo). Si configuro el paso inicial en 1 y no lo incremento, veo los valores esperados. . Acabo de comprobar de nuevo. No funciona como se esperaba.

No puedo entender por qué el valor de reff.current es 2 cuando la devolución de llamada setInterval se llama por segunda vez.

Vaya al enlace de sandbox y

  1. Haga clic en el botón + paso una vez

  2. Abra la consola y vea

 log 1:{step: 1} "reff.current before incr "0 log 2: ref.curret after incr 1 //second time callback is called log 3: {step: 1} "reff.current before incr "2 //this should be 1 log 4: ref.curret after incr 3```
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Su problema ocurre porque está realizando un efecto secundario (actualizando reff.current ) dentro de la función de actualización pasada a setCount .

Los documentos de reacción beta dicen que:

Las funciones de actualización se ejecutan durante la representación, por lo que las funciones de actualización deben ser puras y solo devolver el resultado. No intente establecer el estado desde el interior de ellos ni ejecutar otros efectos secundarios. En modo estricto, React ejecutará cada función de actualización dos veces (pero descartará el segundo resultado) para ayudarlo a encontrar errores.

Está ejecutando su aplicación en StrictMode . Para comprobarlo comentalo:

 const rootElement = document.getElementById('root'); ReactDOM.render( // <StrictMode> <App />, // </StrictMode>, rootElement );

y el problema ya no pasa.

about 4 years ago · Juan Pablo Isaza Report

0

¿Puedes probar este código a continuación,


No estoy seguro de la razón exacta por la que se incrementó el valor, pero usarlo directamente en lugar de regresar de una función funcionó como se esperaba. También funciona para un mayor incremento de pasos.


 import { useEffect, useRef, useState } from "react"; import "./styles.css"; export default function App() { const [count, setCount] = useState(0); const [step, setStep] = useState(0); const reff = useRef(0); useEffect(() => { const id = setInterval(() => { console.log({ step }, "reff.current before incr ", reff.current); debugger; // ------ modified here let newVal = reff.current + step; reff.current = newVal; console.log("ref.curret after incr ", reff.current); setCount(newVal); // ------ modified here }, 6000); return () => clearInterval(id); }, [step]); return ( <> <h1>Count:{count}</h1> <h1>Step: {step}</h1> <input type="button" onClick={(e) => { e.preventDefault(); setStep((prevStep) => { console.log(prevStep); return Number(prevStep) + 1; }); }} value="+ step" /> </> ); }

La imagen del registro registros

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!