reactJS 代码只是保持 运行 并且 setInterval 的运行速度比它应该的要快

reactJS code just keeps running and setInterval is going way faster then it should

我正在制作一个处理两个任务的函数,由于某种原因,该函数导致 setInterval 超快。该函数还阻止条件工作,并使不透明度继续 运行,即使它达到值 1。有人知道为什么会这样吗?

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;

我还附上了一份确实有效的代码副本,但老实说,我想让它在一个 useEffect 挂钩而不是两个挂钩中运行。我觉得这样更有效,而不是创建两个函数。我还觉得我之前的例子中的代码更清晰。要是我能让它工作就好了。

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;

您清除间隔的 return 语句应该从效果函数 return 编辑,但在您的第一个示例中,您是 return 从 designHeader 函数,然后忽略它们,导致没有间隔被清除。在您的工作示例中,它们以正确的方式 returned。

将第一个示例中的效果底部更改为:

const fn1 = designHeader(climber === intro.length, true, 150); 
const fn2 = designHeader(opacitySet > 1, false, 20);
return () => {
    fn1()
    fn2()
}

... 或者简单地 return 区间 id 直接代替函数和 do

const interval1 = designHeader(climber === intro.length, true, 150); 
const interval2 = designHeader(opacitySet > 1, false, 20);
return () => {
    clearInterval(interval1)
    clearInterval(interval2)
}

您的示例之间还有另一个实质性差异;在工作示例中,您的效果具有不同的依赖关系,而在 non-working 示例中,您具有这些依赖关系的联合。这意味着当任何依赖项发生变化时,两个间隔都会被设置和重置,而在工作示例中,当某些依赖项发生变化时,只有一个间隔被更新。这也可能影响它的工作方式,我会说如果效果具有如此不同的依赖性,实际上应该有两种效果而不是一种。也没有任何代码重复可言,那么为什么您不想使用两种效果而不是一种效果呢?基本上,您已经将两个函数合并为一个,代码很少,并且您使用一个布尔值来控制您真正想要使用这些函数中的哪一个;从结构和风格的角度来看,我会说你最好有两个功能和两个效果。