I use "Scrollytelling" in my React application and need to change an svg dynamically according to the current scrollprogress of a section.
For example like this:
useEffect(() => {
if(scrollProgress > 0.5 && scrollProgress < 0.7) foo(); // Called at each change of scrollProgress
if(scrollProgress > 0.7 && scrollProgress < 0.9) bar(); // Called at each change of scrollProgress
// etc.
}, [scrollProgress]);
But I do not want to call these functions at every change of scrollProgress which changes very frequently, I only want to call it once (and not at the first render of the element then I would use an empty dependeny-Array).
Surely this has to be something that happens all the time. I cannot imagine to make a state variable "hasCalled" for each function I want to call in such a scenario and change it accordingly.
Heres an example of where I want to draw an arrow only if the scrollProgress reaches a certain threshold (problem is, it keeps calling the drawArrow() function as scrollProgress keeps on changing)
What is the proper way to handle something like this?
2
Answers
By initialize a
ref
withstart
,end
,action
( which is the function will get executed ),called
( flag to determine if it get called or not ), then check thescrollProgress
is in the range and didn’t get called, then execute theaction
, and then mark thecalled
to betrue
.If you want to fire your effect when some condition changes you should use that condition in the dependency array:
foo
andbar
will be called every time their respective condition changes fromfalse
totrue
. If this is not enough for your case you should add extra logic to ensure that conditions change only once per lifecycle of your component. Or undo the effects when conditions turn back tofalse
: