在Prismic&Gatsby中,每次单击都会重新渲染页面模板

时间:2020-11-03 19:10:48

标签: javascript reactjs gatsby use-effect prismic.io

我一直在尝试诊断为什么单击useEffect组件时<Link>会多次运行,即使有空的依赖关系也是如此。使用this answer.

中的解决方案,我找到了找出问题所在的好方法

基本上,我要添加一个useEffect,其中console记录的组件已被重新渲染,然后一直沿树向上移动,直到找到最高级别的组件为止。渲染。

useEffect(()=>{
  console.log('this component is rendered');
},[]);

我正在使用gatsby-plugin-layout,而我的AppLayout组件是不进行重新渲染的组件,这意味着问题出在我的页面模板之内,如{{3}中所定义},这是单击console<Link>记录页面更改的树上的下一个内容。这么说,我不完全确定问题出在哪里,或者我的AppLayoutgatsby-config.js中是否有什么东西正在抛出它并使这种行为发生。我该如何修复它,以使我的页面不会不断重新渲染?以下包括我的AppLayoutgatsby-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>
        </>
      )}
    />
  );
};

1 个答案:

答案 0 :(得分:0)

很难理解正在发生的事情,但是,我看到了您的useEffect代码

您的代码

useEffect(() => () => {
        if (pathname !== prevPage) {
            setFadeEffectVisible(true);
            setPage(page);
        }
    },
        [pathname],
    );

推荐人

useEffect(() => {
        if (pathname !== prevPage) {
            setFadeEffectVisible(true);
            setPage(page);
        }
    },
        [pathname],
    );