J'exécute setInterval dans useEffect hook pour boucler une fonction, cependant, je veux pouvoir exécuter cette fonction une fois avant d'appliquer le délai (intervalle). Existe-t-il un moyen d'exécuter la fonction une fois dans le hook useEffect avant d'appliquer le délai?
J'ai essayé d'exécuter la fonction une fois à l'intérieur du hook avant la fonction setInterval mais cela ne m'a pas donné les résultats que j'espérais. Il en va de même pour l'exécution de la fonction en dehors du hook useEffect.
const myText = props.text; const textTimeout = 100; const funTextInterval = textTimeout * myText.length const [quickText, setQuickText] = useState([]); const setDelay = (i) => { setTimeout(() => { myFunction(); , textTimeout * i); }; useEffect(() => { setInterval(() => { for (let i = 0; i < myText.length + 1; i++) { setDelay(i); } }, funTextInterval); }, []);
Je m'attends à ce que le forloop
s'exécute une fois avant que le délai de setInterval ne commence, mais le délai se produit avant le code forloop >
3 Réponses :
Vous pouvez séparer votre logique comme ceci:
const myText = props.text; const textTimeout = 100; const funTextInterval = textTimeout * myText.length const [quickText, setQuickText] = useState([]); function applyTextEffect() { for (let i = 0; i < myText.length + 1; i++) { setTimeout(myFunction, textTimeout * i); } } useEffect(() => { applyTextEffect() // call it here immediately to get the effect you want. setInterval(applyTextEffect, funTextInterval); }, []);
Mais notez que ce composant créera un effet indésirable en appelant votre fonction d'effet de texte à chaque mise à jour. UseEffect fonctionne dans chaque mise à jour. Mieux vaut avoir une variable d'état isMounted et implémenter une logique autour d'elle pour appliquer l'effet une seule fois.
EDIT: Il est également sage de stocker l'ID d'intervalle retourné par la fonction setInterval et de l'effacer en retour de useEffect. Sinon, lorsque votre composant va être détruit, vous obtiendrez des exceptions
écrivez une fonction séparée uniquement avec la boucle for.
appelez cette fonction avant d'appeler useEffect ().
depuis useEffect () -> setInterval (), appelez la nouvelle méthode.
Le code non testé est donné ci-dessous à titre d'illustration.
const myText = props.text; const textTimeout = 100; const funTextInterval = textTimeout * myText.length const [quickText, setQuickText] = useState([]); const setDelay = (i) => { setTimeout(() => { myFunction(); , textTimeout * i); }; runloop(){ for (let i = 0; i < myText.length + 1; i++) { setDelay(i); } } useEffect(() => { setInterval(() => { runloop() }, funTextInterval); }, []); runloop();
Sortez la logique de la boucle for dans une méthode et appelez-la avant setInterval et à l'intérieur de setInterval
const myText = props.text; const textTimeout = 100; const funTextInterval = textTimeout * myText.length const [quickText, setQuickText] = useState([]); const setDelay = (i) => { setTimeout(() => { myFunction(); , textTimeout * i); }; useEffect(() => { const loop = () => { for (let i = 0; i < myText.length + 1; i++) { setDelay(i); } } loop(); setInterval(() => { loop(); }, funTextInterval); }, []);
Êtes-vous sûr que le délai ne provient pas de
setTimeout ()
plutôt que de l'intervalle?^^ Cela. Une combinaison de
setInterval ()
etsetTimeout ()
est à l'origine de votre problème.