我一直在尝试诊断为什么单击useEffect
组件时<Link>
会多次运行,即使有空的依赖关系也是如此。使用this answer.
基本上,我要添加一个useEffect
,其中console
记录的组件已被重新渲染,然后一直沿树向上移动,直到找到最高级别的组件为止。渲染。
useEffect(()=>{
console.log('this component is rendered');
},[]);
我正在使用gatsby-plugin-layout,而我的AppLayout
组件是不进行重新渲染的组件,这意味着问题出在我的页面模板之内,如{{3}中所定义},这是单击console
时<Link>
记录页面更改的树上的下一个内容。这么说,我不完全确定问题出在哪里,或者我的AppLayout
或gatsby-config.js
中是否有什么东西正在抛出它并使这种行为发生。我该如何修复它,以使我的页面不会不断重新渲染?以下包括我的AppLayout
和gatsby-config.js
。
谢谢。
gatsby-config.js
/* eslint-disable @typescript-eslint/camelcase */
const path = require('path');
require('dotenv').config({
path: `.env.${process.env.NODE_ENV}`,
});
const site = require('./config/site');
const pathPrefix = site.pathPrefix === '/' ? '' : site.pathPrefix;
module.exports = {
pathPrefix: site.pathPrefix,
siteMetadata: {
siteUrl: site.url + pathPrefix,
pathPrefix,
title: site.title,
titleAlt: site.titleAlt,
titleTemplate: site.titleTemplate,
description: site.description,
banner: site.logo,
headline: site.headline,
siteLanguage: site.siteLanguage,
ogLanguage: site.ogLanguage,
author: site.author,
twitter: site.twitter,
facebook: site.facebook,
},
plugins: [
'gatsby-plugin-react-helmet-async',
'gatsby-plugin-typescript',
'gatsby-plugin-sharp',
'gatsby-plugin-sitemap',
'gatsby-transformer-sharp',
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'images',
path: path.join(__dirname, `src`, `assets`, `images`),
},
},
{
resolve: 'gatsby-plugin-manifest',
options: {
name: 'one-day-doors-and-closets',
short_name: 'starter',
start_url: '/',
background_color: '#663399',
theme_color: '#663399',
display: 'minimal-ui',
icon: 'src/assets/images/icon.png',
},
},
{
resolve: '@sentry/gatsby',
options: {
dsn: process.env.SENTRY_DSN,
enabled: (() => ['production'].indexOf(process.env.NODE_ENV) !== -1)(),
},
},
{
resolve: 'gatsby-plugin-react-svg',
options: {
rule: {
include: path.resolve(__dirname, 'src/assets/svg'),
},
},
},
{
resolve: 'gatsby-source-prismic-graphql',
options: {
repositoryName: `${process.env.PRISMIC_REPOSITORY_NAME}`,
defaultLang: 'en-us',
path: '/preview',
previews: false,
accessToken: `${process.env.PRISMIC_ACCESS_TOKEN}`,
pages: [
{
type: 'Homepage',
match: '/',
component: require.resolve('./src/pages/index.tsx'),
},
{
type: 'Landing',
match: '/:uid',
component: require.resolve('./src/templates/landing.tsx'),
},
{
type: 'Legal',
match: '/:uid',
component: require.resolve('./src/templates/legal.tsx'),
},
{
type: 'Locator',
match: '/:uid',
component: require.resolve('./src/pages/locations.tsx'),
},
{
type: 'Product',
match: '/products/:uid',
component: require.resolve('./src/templates/product.tsx'),
},
],
},
},
{
resolve: 'gatsby-plugin-layout',
options: {
component: require.resolve('./src/components/app-layout/AppLayout.tsx'),
},
},
],
};
AppLayout.tsx
import React, { ReactNode, useEffect, useState } from 'react';
import { Devtools } from 'components/devtools/Devtools';
import { Footer } from 'components/footer/Footer';
import { Header } from 'components/header/Header';
import { NavigationSkipLink } from 'components/navigation-skip-link/NavigationSkipLink';
import { AppContext } from 'contexts/app-context/AppContext';
import { graphql, StaticQuery } from 'gatsby';
import { usePrevious } from 'hooks/use-previous';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import s from './AppLayout.scss';
interface AppLayoutProps {
props: any;
children: ReactNode;
location: any;
}
const isDev = process.env.NODE_ENV === 'development';
export const MainContentId = 'maincontent';
export const timeout = 250;
const NavQuery = graphql`
query NavQuery {
prismic {
allNavigations {
edges {
node {
...NotificationBar
...NavigationItems
...FooterNavigationItems
...LegalNavigationItems
}
}
}
}
}
`;
// eslint-disable-next-line react/display-name
export default ({ children, location: { pathname } }: AppLayoutProps) => {
const [fadeEffectVisible, setFadeEffectVisible] = useState(false);
const [page, setPage] = useState(pathname);
const prevPage = usePrevious(pathname);
useEffect(
() => () => {
if (pathname !== prevPage) {
setFadeEffectVisible(true);
setPage(page);
}
},
[pathname],
);
const handleFadeEffectEntered = () => {
setTimeout(() => {
setFadeEffectVisible(false);
}, 50);
};
return (
<StaticQuery
query={`${NavQuery}`}
render={(data) => (
<>
<AppContext>
<CSSTransition
in={fadeEffectVisible}
timeout={timeout}
classNames={{
enter: s.fadeEffectEnter,
enterActive: s.fadeEffectEnterActive,
enterDone: s.fadeEffectEnterDone,
exit: s.fadeEffectExit,
exitActive: s.fadeEffectExitActive,
}}
onEntered={handleFadeEffectEntered}
>
<div className={s.fadeEffect} aria-hidden="true" />
</CSSTransition>
<NavigationSkipLink />
<Header navigationContent={data.prismic.allNavigations.edges[0].node} />
<TransitionGroup component={null}>
<CSSTransition
key={pathname}
timeout={timeout}
classNames={{
enter: s.pageEnter,
}}
>
<div id={MainContentId} className={s.layout}>
{children}
<Footer navigationItems={data.prismic.allNavigations.edges[0].node} />
{isDev && <Devtools />}
</div>
</CSSTransition>
</TransitionGroup>
</AppContext>
</>
)}
/>
);
};
答案 0 :(得分:0)
很难理解正在发生的事情,但是,我看到了您的useEffect
代码
您的代码
useEffect(() => () => {
if (pathname !== prevPage) {
setFadeEffectVisible(true);
setPage(page);
}
},
[pathname],
);
推荐人
useEffect(() => {
if (pathname !== prevPage) {
setFadeEffectVisible(true);
setPage(page);
}
},
[pathname],
);