I am makig a function that handles two tasks, and for some reason the function is causing setInterval to go super fast. the function also prevents the conditions from working and makes the opacity cotinue to run even after it reaches value of 1. does anyone know why this might be happening?
import React, { useState, useEffect, useRef } from "react";
import Helmet from "react-helmet";
function Main(props) {
let intro = "FELIPE GARCIA DIAZ";
let [climber, setClimber] = useState(0);
let [opacitySet, changeOpacity] = useState(0);
let tagline = useRef();
useEffect(() => {
let designHeader = (condition, isClimber, ms) => {
const genHeaderInfo = setInterval(() => {
if (condition) {
clearInterval(genHeaderInfo);
if (isClimber) {
tagline.current = "Web Developer & Security Specialist";
}
} else {
if (isClimber) {
setClimber((val) => val + 1);
} else {
changeOpacity((val) => val + 0.005);
}
}
}, ms);
return () => {
clearInterval(genHeaderInfo);
};
};
designHeader(climber === intro.length, true, 150);
designHeader(opacitySet > 1, false, 20);
}, [climber, opacitySet, tagline, intro]);
return (
<React.Fragment>
<Helmet>
<title>Felipe GD</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
</Helmet>
<div clasName="row">
<div
id="header"
className="col s12 spacer layer1"
preserveAspectRatio="none"
>
<h1 id="header-title" className="center-align">
{intro.substring(0, climber)}
</h1>
<h4
id="desc"
className="center-align"
style={{ opacity: opacitySet }}
>
{tagline.current}
</h4>
</div>
</div>
</React.Fragment>
);
}
export default Main;
I also attached a copy of the code that does work but honestly I'd like to get this to work in just one useEffect hook instead of two. I feel like its more efficient that way, instead of creating two functions. I also feel like the code is cleaner in my previous example. If only i could get it to work.
import React, { useState, useEffect, useRef } from "react";
import Helmet from "react-helmet";
//import socket from './socket';
function Main(props) {
let intro = "FELIPE GARCIA DIAZ";
let [climber, setClimber] = useState(0);
let [opacitySet, changeOpacity] = useState(0);
let tagline = useRef();
useEffect(() => {
const genName = setInterval(() => {
if(climber === intro.length) {
clearInterval(genName);
tagline.current = "Web Developer & Security Enthusiast"
} else {
setClimber((val) => val + 1);
}
}, 75);
return (() =>{
clearInterval(genName);
});
}, [climber, intro]);
useEffect(()=>{
if(tagline !== null) {
const scaleOpacity = setInterval(() => {
if(opacitySet > 1) {
clearInterval(scaleOpacity);
}else{
changeOpacity((val) => val + 0.0025);
}
}, 10);
return (() => {
clearInterval(scaleOpacity);
})
}
}, [opacitySet, tagline]);
return (
<React.Fragment>
<Helmet>
<title>Felipe GD</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
</Helmet>
<div clasName="row">
<div
id="header"
className="col s12 spacer layer1"
preserveAspectRatio="none"
>
<h1 id="header-title" className="center-align">
{intro.substring(0, climber)}
</h1>
<h4
id="desc"
className="center-align"
style={{ opacity: opacitySet }}
>
{tagline.current}
</h4>
</div>
</div>
</React.Fragment>
);
}
export default Main;
Your return statement where you clear the interval should be returned from the effect function, but in your first example you're returning it from the designHeader
function and then your ignoring them, causing no intervals to be cleared. In your working examples, they are returned in the right way.
Change the bottom of the effect in your first example to:
const fn1 = designHeader(climber === intro.length, true, 150);
const fn2 = designHeader(opacitySet > 1, false, 20);
return () => {
fn1()
fn2()
}
... or simply return the interval ids directly instead of functions and do
const interval1 = designHeader(climber === intro.length, true, 150);
const interval2 = designHeader(opacitySet > 1, false, 20);
return () => {
clearInterval(interval1)
clearInterval(interval2)
}
There is also another substantial difference between your examples; you have different dependencies for your effects in the working example whereas in the non-working example, you have the union of these dependencies. This means that BOTH intervals are set and reset when ANY of the dependencies change whereas in the working examples when some dependencies change only ONE of the intervals are updated. This may also effect how it's working and I would say that if the effects have such different dependencies, there should actually be two effects and not one. There is not any code duplication to speak of either so why do you not want to use two effects instead of one? Basically you have merged two functions with little code in common to one and you use a boolean to control which of these functions you really want to use; from a structural and stylistic viewpoint, I'd say you're better off with two functions and two effects.