首页 > 解决方案 > 先前触发的递归函数没有看到新的道具

问题描述

我有一个函数,它接受文本并将其逐个字符地呈现给 DOM 以创建打字机效果。为了实现这一点,该函数不断地为每个字符一遍又一遍地调用自己。

有时我想跳到另一个级别,所以我的props.chapter更改和我textArray的更新。但是,在 props 和 textArray 更改之前调用的函数仍然会在每次连续调用自身时看到旧值。

如果我在道具更改后第二次触发该函数,则两个调用同时运行,一个显示旧数据,一个显示新数据。

我正在使用带有 Hooks 的 React。

这是我的功能:

const typewriter = () => {
            console.log(props.chapter); //will always show the props at invokation
            sContents = [''];
            iRow = Math.max(0, iIndex - iScrollAt);
            while (iRow < iIndex) {
                sContents[iIndex] += textArray[iRow++];
                sContents[iIndex] = '';
            }

            //This is the text I render to the DOM later
            setText((text) => {
                text[iIndex] = <p key={`line-${iIndex}`}>{sContents[iIndex] + textArray[iIndex].substring(0, iTextPos)}<span className='caret'></span></p>;
                return [...text];
            }); 

            if (iTextPos++ == iArrLength) {
                iTextPos = 0;
                iIndex++;
                if (iIndex != textArray.length) {
                    setSFXon(false);
                    setTimeout(() => {
                        //Clear carat from previous line
                        setText((text) => {
                            if(text[iIndex -1]){
                                text[iIndex-1] = <p key={`line-${iIndex-1}`}>{sContents[iIndex-1] + textArray[iIndex-1].substring(0, iArrLength)}</p>;
                            }
                            text[iIndex] = <p key={`line-${iIndex}`}><span className='caret'></span></p>
                            return [...text];
                        });
                        //Write next line
                        iArrLength = textArray[iIndex].length; //Next line's length
                       //==================
                       //RECURSIVE CALL HERE
                       //==================
                        typewriter()
                    }, 1500);
                }else{
                    //Make last line carat blink
                    setText((text) => {
                        text[iIndex-1] = <p key={`line-${iIndex-1}`}>{sContents[iIndex-1] + textArray[iIndex-1].substring(0, iArrLength)}<span className='caret blink'></span></p>;
                        return [...text];
                    });
                }
            } else {
                //==================
                // RECURSIVE CALL HERE
                //==================
                setTimeout(() => typewriter(), iSpeed);
            }
    }

标签: javascriptreactjs

解决方案


推荐阅读