gpt4 book ai didi

javascript - 如何在标题组件中使用效果(ReactJS/Next.js)

转载 作者:行者123 更新时间:2023-12-04 08:04:18 27 4
gpt4 key购买 nike

我有一个 header.js 组件,它出现在我的 next.js/react 项目的每个页面上。
在里面我创建了一个带有旋转的打字机效果,所以为了启动它,我将代码放在 useEffect 中,如下所示:

export default function Header () {

useEffect(() => {

let delay = 2200;
let input = document.getElementsByClassName('myButton')[0],
index = 0;
const cycleText = () =>{
let randomItem = items[Math.floor(Math.random() * items.length)];

button.setAttribute('value', "Click " + randomItem);
index++;
(index === items.length) ? index = 0 : "";
setTimeout(cycleText, delay);
}

cycleText();
}, []);

return ( ...
重新创建 document.ready就像你对 jQuery 所做的那样,尽管我在使用 useEffect 时遇到了两个问题。 ,一个是如果我更改页面,标题保持不变,但效果代码看起来死了(不再显示文本),二,如果我回到主页,代码在第一次加载时工作正常,现在它显示两个快速成功的旋转实例(好像有两个 useEffect 同时在一个之上,或者类似的东西)。
我越来越了解 useEffect 的工作原理,我知道 [] 使它在页面加载时运行一次,但我认为这就是我所需要的,而且看起来我错了。我应该在 [] 中传递一些可以解决上述两个问题的东西吗?我尝试使用 next.js 路由器,传递 router.pathname,让它在每次页面更改时再次运行,但不起作用。
更新:我注意到上面描述的两个奇怪的行为只发生在从主页到预先生成的页面(通过 staticPaths 和 staticProps)并返回时。
如果我从主页转到用户仪表板(服务器端呈现)并返回它不会与标题中的 useEffect 混淆
更新 2 : 我发现这是我在 里面的保留滚动位置代码_app.js 它确实针对该预先生成的页面以及主页,但实际上不是用户仪表板页面。现在我必须弄清楚如何通过让组件重新渲染来保持滚动位置,因为我已经看到由于同样的问题还有另一段代码使侧边栏变粘并没有启动
这是我的 _app.js 代码:
import React, { useRef, useEffect, memo } from 'react'
import { Provider as NextAuthProvider } from 'next-auth/client'
import { SWRConfig } from 'swr'
import Router, { useRouter } from 'next/router'
import '../public/style.scss'
import { AnimatePresence } from "framer-motion"

export default function MyApp ({ Component, pageProps }) {

const router = useRouter()
const retainedComponents = useRef({})

var isRetainableRoute = false

if (router.pathname == '/' || router.asPath.includes('/author/') || router.asPath.includes('/video/')){
isRetainableRoute = true
}

// Add Component to retainedComponents if we haven't got it already
if (isRetainableRoute && !retainedComponents.current[router.asPath]) {
const MemoComponent = memo(Component)
retainedComponents.current[router.asPath] = {
component: <MemoComponent {...pageProps} />,
scrollPos: 0
}
}

// Save the scroll position of current page before leaving
const handleRouteChangeStart = url => {
if (isRetainableRoute) {
retainedComponents.current[router.asPath].scrollPos = window.scrollY
}
}

// Save scroll position - requires an up-to-date router.asPath
useEffect(() => {
router.events.on('routeChangeStart', handleRouteChangeStart)
return () => {
router.events.off('routeChangeStart', handleRouteChangeStart)
}
}, [router.asPath])

// Scroll to the saved position when we load a retained component
useEffect(() => {
if (isRetainableRoute) {
window.scrollTo(0, retainedComponents.current[router.asPath].scrollPos)
}
}, [Component, pageProps])

return (
<NextAuthProvider
options={{
clientMaxAge: 60,
keepAlive: 61
}}
session={pageProps.session}
>
<SWRConfig
value={{
revalidateOnFocus: false
}}
>
<AnimatePresence exitBeforeEnter>
<div>
<div style={{ display: isRetainableRoute ? 'block' : 'none' }}>
{Object.entries(retainedComponents.current).map(([path, c]) => (
<div
key={path}
style={{ display: router.asPath === path ? 'block' : 'none' }}
>
{c.component}
</div>
))}
</div>
{!isRetainableRoute && <Component {...pageProps} />}
</div>
</AnimatePresence>
</SWRConfig>
</NextAuthProvider>
)
}

最佳答案

通过递归调用 cycleTextsetTimeout您创建了一个永不结束的函数,即使 Header 组件被卸载(当您更改页面时会发生这种情况)。当移动到再次具有 Header 组件的页面时,将创建该 Header 组件并且 useEffect挂载时再次执行一次,因此又出现了一次无休止的cycleText功能启动等。
你可以把 console.log在您的 cycleText功能来查看当您移动到另一个页面并返回具有标题的页面时它会越来越快地记录。
我认为最好避免使用递归无限函数以避免使用堆栈内存,并使用 setInterval反而。更重要的是:当组件被卸载时,不要忘记停止你的函数。对于 useEffect返回时完成,您可以调用clearInterval那里。
你可以这样做:

  useEffect(() => {
let delay = 2200;
let input = document.getElementsByClassName('myButton')[0],
index = 0;

const interval = setInterval(() => {
let randomItem = items[Math.floor(Math.random() * items.length)];
button.setAttribute('value', "Click " + randomItem);
index++;
if(index >= items.length){
index = 0
}
}, delay);

return () => {
clearInterval(interval);
};
}, []);

关于javascript - 如何在标题组件中使用效果(ReactJS/Next.js),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66303112/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com