esto no es un duplicado porque traté de agregar una función de actualización y no funcionó, este es el código que tengo
const [counter, setCounter] = useState(0); useEffect(()=> { const fetchSessions =async ()=> { instance.events.sessionCreated({fromBlock:0}).on("data",async (evt)=>{ handleSessionCreatd(evt)}) } fetchSessions(); },[]); const handleSessionCreatd =async (event)=> { let index = event.returnValues.id -1; let session = await instance.methods.sessions(index).call(); console.log("index is at:",index); setCounter(counter => counter+1); //setCounter(prev=>index); console.log("counter is at",counter); } quería ejecutar una devolución de llamada a las sesiones recién creadas, así que lo puse dentro useEffect() con una matriz vacía para registrar mi devolución de llamada solo una vez (ya que eventListner sigue actualizándose automáticamente), el valor del índice se actualiza con éxito, sin embargo, el valor de mi contador no se actualiza
¿Cómo actualizo mi contador?
aunque estoy usando useEffect() con una matriz vacía, el resultado es un poco extraño porque imprime la ejecución dos veces:
el índice está en 0
el contador esta en 0
el índice está en 1
el contador esta en 0
.
.
.
el índice está en 10
el contador esta en 0
luego imprime la lista anterior otra vez a partir de 0 (completamente la misma lista, el contador aún no se actualiza), ¿qué causa este comportamiento?
pd: el evento es de web3.js. e incluso si elimino el comentario del segundo setState, todavía no se incrementa (pensé que tal vez de alguna manera todavía estaba tomando el valor capturado del cierre)
setState es asíncrono, significa que console.log no puede mostrar el valor antes de que haya cambiado
Como puedo ver, está pasando el controlador solo una vez en la inicialización, y así el valor counter dentro del controlador se recuperará del cierre. Dado que el counter de inicialización es 0, en cada registro imprimirá ese mismo 0 desde el cierre que se construyó en esa primera (y única) vez que pasó el controlador de eventos. Intente iniciar sesión fuera del controlador de eventos y ver cuál es el valor de counter . Si necesita counter en el controlador de eventos, deberá incluir algunas dependencias en useEffect para reconstruir el cierre desde el que está leyendo.
La solución fue deshabilitar React.strictMode en index.js (simplemente elimine la línea), además, dado que setState es asíncrono, la ejecución se mueve al registro de la consola sin ejecutar necesariamente setState, por lo tanto, genera valores antiguos. entonces, para obtener el valor final, simplemente consola. Regístrese fuera de useEffect, también le dará una pista sobre cuántas veces React vuelve a renderizar y sus técnicas de optimización.