Je ne comprends pas pourquoi, lorsque j'utilise setTimeout
function, mon composant de réaction démarre dans le fichier console.log infini. Tout fonctionne, mais les ordinateurs commencent à prendre du retard. Certaines personnes disent que cette fonction modifie temporairement mon état et ce composant de ré-affichage, ce qui active le nouveau minuteur, etc. Maintenant, j'ai besoin de comprendre comment effacer c'est juste.
export default function Loading() {
// if data fetching is slow, after 1 sec i will show some loading animation
const [showLoading, setShowLoading] = useState(true)
let timer1 = setTimeout(() => setShowLoading(true), 1000)
console.log('this message will render every second')
return 1
}
Effacer dans une version différente du code ne contribuant pas à:
const [showLoading, setShowLoading] = useState(true)
let timer1 = setTimeout(() => setShowLoading(true), 1000)
useEffect(
() => {
return () => {
clearTimeout(timer1)
}
},
[showLoading]
)
La fonction de retour dans useEffect
s'exécute chaque fois que useEffect
est exécuté (à l'exception de la première exécution lors du montage du composant). Pensez-y car chaque fois qu'il y a une nouvelle exécution useEffect
, l'ancienne est supprimée.
export default function Loading() {
const [showLoading, setShowLoading] = useState(false)
useEffect(
() => {
let timer1 = setTimeout(() => setShowLoading(true), 1000)
// this will clear Timeout when component unmont like in willComponentUnmount
return () => {
clearTimeout(timer1)
}
},
[] //useEffect will run only one time
//if you pass a value to array, like this [data] than clearTimeout will run every time this value changes (useEffect re-run)
)
return showLoading && <div>I will be visible after ~1000ms</div>
}
export default function Loading() {
const [showLoading, setShowLoading] = useState(false)
const timerToClearSomewhere = useRef(false) //now you can pass timer to another component
useEffect(
() => {
timerToClearSomewhere.current = setInterval(() => setShowLoading(true), 1000)
return () => {
clearInterval(timerToClearSomewhere.current)
}
},
[]
)
//here we can imitate clear from somewhere else place
useEffect(() => {
setTimeout(() => clearInterval(timerToClearSomewhere.current), 15000)
}, [])
return showLoading && <div>I will be visible after ~1000ms</div>
}
Si vous avez besoin de gérer la file d'attente (changement d'état dans timer/intervalle), cherchez ma réponse ici.
Votre ordinateur était à la traîne parce que vous avez probablement oublié de transmettre le tableau vide en tant que deuxième argument de useEffect
et a déclenché un setState
dans le rappel. Cela provoque une boucle infinie parce que useEffect
est déclenché lors du rendu.
Voici un moyen efficace de définir une minuterie sur mount et de la supprimer lors du démontage:
function App() {
React.useEffect(() => {
const timer = window.setInterval(() => {
console.log('1 second has passed');
}, 1000);
return () => { // Return callback to run on unmount.
window.clearInterval(timer);
};
}, []); // Pass in empty array to run useEffect only on mount.
return (
<div>
Timer Example
</div>
);
}
ReactDOM.render(
<div>
<App />
</div>,
document.querySelector("#app")
);
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>