Estoy empezando a aprender React y me preguntaba por qué mi Contador no funciona :( Mi objetivo es: cuando presionas el botón, la función Contador comienza a "contar" y muestra el estado "contar" en el td. No sé qué estoy haciendo mal
import React, { useState } from "react"; function Clock() { const customStyle = { fontSize: "100px" }; const tdStyle = "px-3 border border-dark border-3 rounded bg-secondary"; //------------------------------------------------------------------------- // THIS FUNCTION const [count, setCount] = useState(0); function Counter(){ setCount(count + 1) setInterval(Counter, 1000) } return ( <div className="rounded border border-dark border-3"> <table> <tr style={customStyle}> <td className={tdStyle}> <i className="fa-solid fa-clock"></i> </td> <td className={tdStyle}>0</td> <td className={tdStyle}>0</td> <td className={tdStyle}>0</td> <td className={tdStyle}>0</td> <td className={tdStyle}>0</td> <td className={tdStyle}>{count}</td> //here is showed </tr> </table> <button onClick={Counter}>Pulsar</button> //button </div> ); } export default Clock;Esto funciona con segundos reales.
function Counter(){ setCount(new Date().getSeconds()) setInterval(Counter, 1000) }Pero no es lo que quiero. Quiero un contador simple.
Además, ¿cómo podría usar el evento "onLoad" en este código? porque cuando se carga la página, ¿comienza a contar y representarla en la página?
¡¡Gracias de antemano!!
En primer lugar, debe colocar su setInterval en un enlace useEffect porque actualmente está creando un nuevo intervalo cada vez que su estado se actualiza (es decir, cada segundo), lo que ralentizará drásticamente su aplicación. En segundo lugar, debe usar la función de limpieza useEffect para eliminar el intervalo cada vez que su componente se vuelve a renderizar para evitar la creación de intervalos duplicados. Finalmente, dado que su estado depende de una instantánea de estado anterior (es decir, el valor de conteo anterior), debe actualizar su estado mediante una devolución de llamada (para asegurarse de acceder a la instantánea de estado más reciente)
useEffect(() => { function counter(){ setCount(prevState => prevState + 1) } let countInterval = setInterval(counter, 1000) return () => clearInterval(countInterval) }, []) Dado que está llamando a useEffect cada vez que se actualiza el conteo, podría (y probablemente debería) usar setTimeout en lugar de setInterval . En ese caso, no necesitaría la función de limpieza.
Si entiendo cómo funciona useState correctamente, creo que se está encontrando con algunos problemas asincrónicos con su estado de conteo, lo que explicaría por qué funciona su ejemplo de "segundos reales".
Sugeriría mover su función setInterval() a un gancho useEffect . El gancho useEffect también sería la respuesta a su pregunta onLoad .
import React, { useState, useEffect } from "react"; function Clock() { const customStyle = { fontSize: "100px" }; const tdStyle = "px-3 border border-dark border-3 rounded bg-secondary"; //------------------------------------------------------------------------- // THIS FUNCTION const [count, setCount] = useState(0); useEffect(() => { setInterval(counter, 1000); }, []); function Counter(){ setCount(count + 1) } return ( <div className="rounded border border-dark border-3"> <table> <tr style={customStyle}> <td className={tdStyle}> <i className="fa-solid fa-clock"></i> </td> <td className={tdStyle}>0</td> <td className={tdStyle}>0</td> <td className={tdStyle}>0</td> <td className={tdStyle}>0</td> <td className={tdStyle}>0</td> <td className={tdStyle}>{count}</td> //here is showed </tr> </table> <button onClick={Counter}>Pulsar</button> //button </div> ); } export default Clock;No estoy 100 % seguro de que esto funcione como se espera, ya que no puedo probarlo en este momento, pero creo que esto es lo que estás buscando. Aquí también hay documentación sobre useEffect, https://reactjs.org/docs/hooks-effect.html